Merge "Revert "Revert "Revert "User consent for Logcat data access""""
This commit is contained in:
@@ -214,14 +214,6 @@ public abstract class ActivityManagerInternal {
|
||||
*/
|
||||
public abstract boolean isSystemReady();
|
||||
|
||||
/**
|
||||
* Returns package name given pid.
|
||||
*
|
||||
* @param pid The pid we are searching package name for.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String getPackageNameByPid(int pid);
|
||||
|
||||
/**
|
||||
* Sets if the given pid has an overlay UI or not.
|
||||
*
|
||||
|
||||
@@ -22,7 +22,5 @@ package android.os.logcat;
|
||||
interface ILogcatManagerService {
|
||||
void startThread(in int uid, in int gid, in int pid, in int fd);
|
||||
void finishThread(in int uid, in int gid, in int pid, in int fd);
|
||||
void approve(in int uid, in int gid, in int pid, in int fd);
|
||||
void decline(in int uid, in int gid, in int pid, in int fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -6616,14 +6616,6 @@
|
||||
android:exported="false">
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.android.server.logcat.LogAccessConfirmationActivity"
|
||||
android:theme="@style/Theme.Dialog.Confirmation"
|
||||
android:excludeFromRecents="true"
|
||||
android:process=":ui"
|
||||
android:label="@string/log_access_confirmation_title"
|
||||
android:exported="false">
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.android.server.notification.NASLearnMoreActivity"
|
||||
android:theme="@style/Theme.Dialog.Confirmation"
|
||||
android:excludeFromRecents="true"
|
||||
|
||||
@@ -5719,20 +5719,6 @@
|
||||
<!-- Title for the harmful app warning dialog. [CHAR LIMIT=40] -->
|
||||
<string name="harmful_app_warning_title">Harmful app detected</string>
|
||||
|
||||
<!-- Title for the log access confirmation dialog. [CHAR LIMIT=40] -->
|
||||
<string name="log_access_confirmation_title">System log access request</string>
|
||||
<!-- Label for the allow button on the log access confirmation dialog. [CHAR LIMIT=20] -->
|
||||
<string name="log_access_confirmation_allow">Only this time</string>
|
||||
<!-- Label for the deny button on the log access confirmation dialog. [CHAR LIMIT=20] -->
|
||||
<string name="log_access_confirmation_deny">Don\u2019t allow</string>
|
||||
|
||||
<!-- Content for the log access confirmation dialog. [CHAR LIMIT=NONE]-->
|
||||
<string name="log_access_confirmation_body"><xliff:g id="log_access_app_name" example="Example App">%s</xliff:g> requests system logs for functional debugging.
|
||||
These logs might contain information that apps and services on your device have written.</string>
|
||||
|
||||
<!-- Privacy notice do not show [CHAR LIMIT=20] -->
|
||||
<string name="log_access_do_not_show_again">Don\u2019t show again</string>
|
||||
|
||||
<!-- Text describing a permission request for one app to show another app's
|
||||
slices [CHAR LIMIT=NONE] -->
|
||||
<string name="slices_permission_request"><xliff:g id="app" example="Example App">%1$s</xliff:g> wants to show <xliff:g id="app_2" example="Other Example App">%2$s</xliff:g> slices</string>
|
||||
|
||||
@@ -3868,11 +3868,6 @@
|
||||
<java-symbol type="string" name="harmful_app_warning_title" />
|
||||
<java-symbol type="layout" name="harmful_app_warning_dialog" />
|
||||
|
||||
<java-symbol type="string" name="log_access_confirmation_allow" />
|
||||
<java-symbol type="string" name="log_access_confirmation_deny" />
|
||||
<java-symbol type="string" name="log_access_confirmation_title" />
|
||||
<java-symbol type="string" name="log_access_confirmation_body" />
|
||||
|
||||
<java-symbol type="string" name="config_defaultAssistantAccessComponent" />
|
||||
|
||||
<java-symbol type="string" name="slices_permission_request" />
|
||||
|
||||
@@ -16120,23 +16120,6 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
return mSystemReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns package name by pid.
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public String getPackageNameByPid(int pid) {
|
||||
synchronized (mPidsSelfLocked) {
|
||||
final ProcessRecord app = mPidsSelfLocked.get(pid);
|
||||
|
||||
if (app != null && app.info != null) {
|
||||
return app.info.packageName;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the given pid has an overlay UI or not.
|
||||
*
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.server.logcat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.os.Bundle;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.logcat.ILogcatManagerService;
|
||||
import android.util.Slog;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.app.AlertController;
|
||||
|
||||
|
||||
/**
|
||||
* This dialog is shown to the user before an activity in a harmful app is launched.
|
||||
*
|
||||
* See {@code PackageManager.setLogcatAppInfo} for more info.
|
||||
*/
|
||||
public class LogAccessConfirmationActivity extends AlertActivity implements
|
||||
DialogInterface.OnClickListener {
|
||||
private static final String TAG = LogAccessConfirmationActivity.class.getSimpleName();
|
||||
|
||||
private String mPackageName;
|
||||
private IntentSender mTarget;
|
||||
private final ILogcatManagerService mLogcatManagerService =
|
||||
ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat"));
|
||||
|
||||
private int mUid;
|
||||
private int mGid;
|
||||
private int mPid;
|
||||
private int mFd;
|
||||
|
||||
private static final String EXTRA_UID = "uid";
|
||||
private static final String EXTRA_GID = "gid";
|
||||
private static final String EXTRA_PID = "pid";
|
||||
private static final String EXTRA_FD = "fd";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
|
||||
mUid = intent.getIntExtra("uid", 0);
|
||||
mGid = intent.getIntExtra("gid", 0);
|
||||
mPid = intent.getIntExtra("pid", 0);
|
||||
mFd = intent.getIntExtra("fd", 0);
|
||||
|
||||
final AlertController.AlertParams p = mAlertParams;
|
||||
p.mTitle = getString(R.string.log_access_confirmation_title);
|
||||
p.mView = createView();
|
||||
|
||||
p.mPositiveButtonText = getString(R.string.log_access_confirmation_allow);
|
||||
p.mPositiveButtonListener = this;
|
||||
p.mNegativeButtonText = getString(R.string.log_access_confirmation_deny);
|
||||
p.mNegativeButtonListener = this;
|
||||
|
||||
mAlert.installContent(mAlertParams);
|
||||
}
|
||||
|
||||
private View createView() {
|
||||
final View view = getLayoutInflater().inflate(R.layout.harmful_app_warning_dialog,
|
||||
null /*root*/);
|
||||
((TextView) view.findViewById(R.id.app_name_text))
|
||||
.setText(mPackageName);
|
||||
((TextView) view.findViewById(R.id.message))
|
||||
.setText(getIntent().getExtras().getString("body"));
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
try {
|
||||
mLogcatManagerService.approve(mUid, mGid, mPid, mFd);
|
||||
} catch (Throwable t) {
|
||||
Slog.e(TAG, "Could not start the LogcatManagerService.", t);
|
||||
}
|
||||
finish();
|
||||
break;
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
try {
|
||||
mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
|
||||
} catch (Throwable t) {
|
||||
Slog.e(TAG, "Could not start the LogcatManagerService.", t);
|
||||
}
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Intent for a LogAccessConfirmationActivity.
|
||||
*/
|
||||
public static Intent createIntent(Context context, String targetPackageName,
|
||||
IntentSender target, int uid, int gid, int pid, int fd) {
|
||||
final Intent intent = new Intent();
|
||||
intent.setClass(context, LogAccessConfirmationActivity.class);
|
||||
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName);
|
||||
intent.putExtra(EXTRA_UID, uid);
|
||||
intent.putExtra(EXTRA_GID, gid);
|
||||
intent.putExtra(EXTRA_PID, pid);
|
||||
intent.putExtra(EXTRA_FD, fd);
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,36 +16,20 @@
|
||||
|
||||
package com.android.server.logcat;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningAppProcessInfo;
|
||||
import android.app.ActivityManagerInternal;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.ILogd;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.logcat.ILogcatManagerService;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.notification.SystemNotificationChannels;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Service responsible for managing the access to Logcat.
|
||||
* Service responsible for manage the access to Logcat.
|
||||
*/
|
||||
public final class LogcatManagerService extends SystemService {
|
||||
|
||||
@@ -54,43 +38,6 @@ public final class LogcatManagerService extends SystemService {
|
||||
private final BinderService mBinderService;
|
||||
private final ExecutorService mThreadExecutor;
|
||||
private ILogd mLogdService;
|
||||
private NotificationManager mNotificationManager;
|
||||
private @NonNull ActivityManager mActivityManager;
|
||||
private ActivityManagerInternal mActivityManagerInternal;
|
||||
private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2;
|
||||
private static int sUidImportanceListenerCount = 0;
|
||||
private static final int AID_SHELL_UID = 2000;
|
||||
|
||||
// TODO This allowlist is just a temporary workaround for the tests:
|
||||
// FrameworksServicesTests
|
||||
// PlatformRuleTests
|
||||
// After adapting the test suites, the allowlist will be removed in
|
||||
// the upcoming bug fix patches.
|
||||
private static final String[] ALLOWABLE_TESTING_PACKAGES = {
|
||||
"android.platform.test.rule.tests",
|
||||
"com.android.frameworks.servicestests"
|
||||
};
|
||||
|
||||
// TODO Same as the above ALLOWABLE_TESTING_PACKAGES.
|
||||
private boolean isAllowableTestingPackage(int uid) {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
|
||||
String[] packageNames = pm.getPackagesForUid(uid);
|
||||
|
||||
if (ArrayUtils.isEmpty(packageNames)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String name : packageNames) {
|
||||
Slog.e(TAG, "isAllowableTestingPackage: " + name);
|
||||
|
||||
if (Arrays.asList(ALLOWABLE_TESTING_PACKAGES).contains(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
private final class BinderService extends ILogcatManagerService.Stub {
|
||||
@Override
|
||||
@@ -104,197 +51,6 @@ public final class LogcatManagerService extends SystemService {
|
||||
// the logd data access is finished.
|
||||
mThreadExecutor.execute(new LogdMonitor(uid, gid, pid, fd, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void approve(int uid, int gid, int pid, int fd) {
|
||||
try {
|
||||
getLogdService().approve(uid, gid, pid, fd);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decline(int uid, int gid, int pid, int fd) {
|
||||
try {
|
||||
getLogdService().decline(uid, gid, pid, fd);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ILogd getLogdService() {
|
||||
synchronized (LogcatManagerService.this) {
|
||||
if (mLogdService == null) {
|
||||
LogcatManagerService.this.addLogdService();
|
||||
}
|
||||
return mLogdService;
|
||||
}
|
||||
}
|
||||
|
||||
private String getBodyString(Context context, String callingPackage, int uid) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
return context.getString(
|
||||
com.android.internal.R.string.log_access_confirmation_body,
|
||||
pm.getApplicationInfoAsUser(callingPackage, PackageManager.MATCH_DIRECT_BOOT_AUTO,
|
||||
UserHandle.getUserId(uid)).loadLabel(pm));
|
||||
} catch (NameNotFoundException e) {
|
||||
// App name is unknown.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotification(int notificationId, String clientInfo, int uid, int gid, int pid,
|
||||
int fd) {
|
||||
|
||||
final ActivityManagerInternal activityManagerInternal =
|
||||
LocalServices.getService(ActivityManagerInternal.class);
|
||||
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
String packageName = activityManagerInternal.getPackageNameByPid(pid);
|
||||
if (packageName != null) {
|
||||
String notificationBody = getBodyString(mContext, packageName, uid);
|
||||
|
||||
final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext,
|
||||
packageName, null, uid, gid, pid, fd);
|
||||
|
||||
if (notificationBody == null) {
|
||||
// Decline the logd access if the nofitication body is unknown
|
||||
Slog.e(TAG, "Unknown notification body, declining the logd access");
|
||||
declineLogdAccess(uid, gid, pid, fd);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Next version will replace notification with dialogue
|
||||
// per UX guidance.
|
||||
generateNotificationWithBodyContent(notificationId, clientInfo, notificationBody,
|
||||
mIntent);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
String[] packageNames = pm.getPackagesForUid(uid);
|
||||
|
||||
if (ArrayUtils.isEmpty(packageNames)) {
|
||||
// Decline the logd access if the app name is unknown
|
||||
Slog.e(TAG, "Unknown calling package name, declining the logd access");
|
||||
declineLogdAccess(uid, gid, pid, fd);
|
||||
return;
|
||||
}
|
||||
|
||||
String firstPackageName = packageNames[0];
|
||||
|
||||
if (firstPackageName == null || firstPackageName.length() == 0) {
|
||||
// Decline the logd access if the package name from uid is unknown
|
||||
Slog.e(TAG, "Unknown calling package name, declining the logd access");
|
||||
declineLogdAccess(uid, gid, pid, fd);
|
||||
return;
|
||||
}
|
||||
|
||||
String notificationBody = getBodyString(mContext, firstPackageName, uid);
|
||||
|
||||
final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext,
|
||||
firstPackageName, null, uid, gid, pid, fd);
|
||||
|
||||
if (notificationBody == null) {
|
||||
Slog.e(TAG, "Unknown notification body, declining the logd access");
|
||||
declineLogdAccess(uid, gid, pid, fd);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Next version will replace notification with dialogue
|
||||
// per UX guidance.
|
||||
generateNotificationWithBodyContent(notificationId, clientInfo,
|
||||
notificationBody, mIntent);
|
||||
}
|
||||
|
||||
private void declineLogdAccess(int uid, int gid, int pid, int fd) {
|
||||
try {
|
||||
getLogdService().decline(uid, gid, pid, fd);
|
||||
} catch (RemoteException ex) {
|
||||
Slog.e(TAG, "Fails to call remote functions ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateNotificationWithBodyContent(int notificationId, String clientInfo,
|
||||
String notificationBody, Intent intent) {
|
||||
final Notification.Builder notificationBuilder = new Notification.Builder(
|
||||
mContext,
|
||||
SystemNotificationChannels.ACCESSIBILITY_SECURITY_POLICY);
|
||||
intent.setFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
intent.setIdentifier(String.valueOf(notificationId) + clientInfo);
|
||||
intent.putExtra("body", notificationBody);
|
||||
|
||||
notificationBuilder
|
||||
.setSmallIcon(R.drawable.ic_info)
|
||||
.setContentTitle(
|
||||
mContext.getString(R.string.log_access_confirmation_title))
|
||||
.setContentText(notificationBody)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(mContext, 0, intent,
|
||||
PendingIntent.FLAG_IMMUTABLE))
|
||||
.setTicker(mContext.getString(R.string.log_access_confirmation_title))
|
||||
.setOnlyAlertOnce(true)
|
||||
.setAutoCancel(true);
|
||||
mNotificationManager.notify(notificationId, notificationBuilder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* A class which watches an uid for background access and notifies the logdMonitor when
|
||||
* the package status becomes foreground (importance change)
|
||||
*/
|
||||
private class UidImportanceListener implements ActivityManager.OnUidImportanceListener {
|
||||
private final int mExpectedUid;
|
||||
private final int mExpectedGid;
|
||||
private final int mExpectedPid;
|
||||
private final int mExpectedFd;
|
||||
private int mExpectedImportance;
|
||||
private int mCurrentImportance = RunningAppProcessInfo.IMPORTANCE_GONE;
|
||||
|
||||
UidImportanceListener(int uid, int gid, int pid, int fd, int importance) {
|
||||
mExpectedUid = uid;
|
||||
mExpectedGid = gid;
|
||||
mExpectedPid = pid;
|
||||
mExpectedFd = fd;
|
||||
mExpectedImportance = importance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidImportance(int uid, int importance) {
|
||||
if (uid == mExpectedUid) {
|
||||
mCurrentImportance = importance;
|
||||
|
||||
/**
|
||||
* 1) If the process status changes to foreground, send a notification
|
||||
* for user consent.
|
||||
* 2) If the process status remains background, we decline logd access request.
|
||||
**/
|
||||
if (importance <= RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE) {
|
||||
String clientInfo = getClientInfo(uid, mExpectedGid, mExpectedPid, mExpectedFd);
|
||||
sendNotification(0, clientInfo, uid, mExpectedGid, mExpectedPid,
|
||||
mExpectedFd);
|
||||
mActivityManager.removeOnUidImportanceListener(this);
|
||||
|
||||
synchronized (LogcatManagerService.this) {
|
||||
sUidImportanceListenerCount--;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getLogdService().decline(uid, mExpectedGid, mExpectedPid, mExpectedFd);
|
||||
} catch (RemoteException ex) {
|
||||
Slog.e(TAG, "Fails to call remote functions ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getClientInfo(int uid, int gid, int pid, int fd) {
|
||||
return "UID=" + Integer.toString(uid) + " GID=" + Integer.toString(gid) + " PID="
|
||||
+ Integer.toString(pid) + " FD=" + Integer.toString(fd);
|
||||
}
|
||||
|
||||
private class LogdMonitor implements Runnable {
|
||||
@@ -318,7 +74,9 @@ public final class LogcatManagerService extends SystemService {
|
||||
}
|
||||
|
||||
/**
|
||||
* LogdMonitor generates a prompt for users.
|
||||
* The current version grant the permission by default.
|
||||
* And track the logd access.
|
||||
* The next version will generate a prompt for users.
|
||||
* The users decide whether the logd access is allowed.
|
||||
*/
|
||||
@Override
|
||||
@@ -328,61 +86,10 @@ public final class LogcatManagerService extends SystemService {
|
||||
}
|
||||
|
||||
if (mStart) {
|
||||
|
||||
// TODO See the comments of ALLOWABLE_TESTING_PACKAGES.
|
||||
if (isAllowableTestingPackage(mUid)) {
|
||||
try {
|
||||
getLogdService().approve(mUid, mGid, mPid, mFd);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the access request is coming from adb shell, approve the logd access
|
||||
if (mUid == AID_SHELL_UID) {
|
||||
try {
|
||||
getLogdService().approve(mUid, mGid, mPid, mFd);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final int procState = LocalServices.getService(ActivityManagerInternal.class)
|
||||
.getUidProcessState(mUid);
|
||||
// If the process is foreground, send a notification for user consent
|
||||
if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
|
||||
String clientInfo = getClientInfo(mUid, mGid, mPid, mFd);
|
||||
sendNotification(0, clientInfo, mUid, mGid, mPid, mFd);
|
||||
} else {
|
||||
/**
|
||||
* If the process is background, add a background process change listener and
|
||||
* monitor if the process status changes.
|
||||
* To avoid clients registering multiple listeners, we limit the number of
|
||||
* maximum listeners to MAX_UID_IMPORTANCE_COUNT_LISTENER.
|
||||
**/
|
||||
if (mActivityManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (LogcatManagerService.this) {
|
||||
if (sUidImportanceListenerCount < MAX_UID_IMPORTANCE_COUNT_LISTENER) {
|
||||
// Trigger addOnUidImportanceListener when there is an update from
|
||||
// the importance of the process
|
||||
mActivityManager.addOnUidImportanceListener(new UidImportanceListener(
|
||||
mUid, mGid, mPid, mFd,
|
||||
RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE),
|
||||
RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE);
|
||||
sUidImportanceListenerCount++;
|
||||
} else {
|
||||
try {
|
||||
getLogdService().decline(mUid, mGid, mPid, mFd);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
mLogdService.approve(mUid, mGid, mPid, mFd);
|
||||
} catch (RemoteException ex) {
|
||||
Slog.e(TAG, "Fails to call remote functions ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -393,8 +100,6 @@ public final class LogcatManagerService extends SystemService {
|
||||
mContext = context;
|
||||
mBinderService = new BinderService();
|
||||
mThreadExecutor = Executors.newCachedThreadPool();
|
||||
mActivityManager = context.getSystemService(ActivityManager.class);
|
||||
mNotificationManager = mContext.getSystemService(NotificationManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -409,4 +114,5 @@ public final class LogcatManagerService extends SystemService {
|
||||
private void addLogdService() {
|
||||
mLogdService = ILogd.Stub.asInterface(ServiceManager.getService("logd"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user