Merge "Configurable sampling rate for hidden API access log events." into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
fb55bd8706
@@ -165,6 +165,11 @@ public class ZygoteProcess {
|
||||
*/
|
||||
private List<String> mApiBlacklistExemptions = Collections.emptyList();
|
||||
|
||||
/**
|
||||
* Proportion of hidden API accesses that should be logged to the event log; 0 - 0x10000.
|
||||
*/
|
||||
private int mHiddenApiAccessLogSampleRate;
|
||||
|
||||
/**
|
||||
* The state of the connection to the primary zygote.
|
||||
*/
|
||||
@@ -478,6 +483,21 @@ public class ZygoteProcess {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the precentage of detected hidden API accesses that are logged to the event log.
|
||||
*
|
||||
* <p>This rate will take affect for all new processes forked from the zygote after this call.
|
||||
*
|
||||
* @param rate An integer between 0 and 0x10000 inclusive. 0 means no event logging.
|
||||
*/
|
||||
public void setHiddenApiAccessLogSampleRate(int rate) {
|
||||
synchronized (mLock) {
|
||||
mHiddenApiAccessLogSampleRate = rate;
|
||||
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
|
||||
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void maybeSetApiBlacklistExemptions(ZygoteState state, boolean sendIfEmpty) {
|
||||
if (state == null || state.isClosed()) {
|
||||
@@ -505,6 +525,29 @@ public class ZygoteProcess {
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeSetHiddenApiAccessLogSampleRate(ZygoteState state) {
|
||||
if (state == null || state.isClosed()) {
|
||||
return;
|
||||
}
|
||||
if (mHiddenApiAccessLogSampleRate == -1) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
state.writer.write(Integer.toString(1));
|
||||
state.writer.newLine();
|
||||
state.writer.write("--hidden-api-log-sampling-rate="
|
||||
+ Integer.toString(mHiddenApiAccessLogSampleRate));
|
||||
state.writer.newLine();
|
||||
state.writer.flush();
|
||||
int status = state.inputStream.readInt();
|
||||
if (status != 0) {
|
||||
Slog.e(LOG_TAG, "Failed to set hidden API log sampling rate; status " + status);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
Slog.e(LOG_TAG, "Failed to set hidden API log sampling rate", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to open socket to Zygote process if not already open. If
|
||||
* already open, does nothing. May block and retry. Requires that mLock be held.
|
||||
@@ -520,6 +563,7 @@ public class ZygoteProcess {
|
||||
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
|
||||
}
|
||||
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
|
||||
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
|
||||
}
|
||||
if (primaryZygoteState.matches(abi)) {
|
||||
return primaryZygoteState;
|
||||
@@ -533,6 +577,7 @@ public class ZygoteProcess {
|
||||
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
|
||||
}
|
||||
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
|
||||
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
|
||||
}
|
||||
|
||||
if (secondaryZygoteState.matches(abi)) {
|
||||
|
||||
@@ -11765,6 +11765,15 @@ public final class Settings {
|
||||
public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS =
|
||||
"hidden_api_blacklist_exemptions";
|
||||
|
||||
/**
|
||||
* Sampling rate for hidden API access event logs, as an integer in the range 0 to 0x10000
|
||||
* inclusive.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String HIDDEN_API_ACCESS_LOG_SAMPLING_RATE =
|
||||
"hidden_api_access_log_sampling_rate";
|
||||
|
||||
/**
|
||||
* Hidden API enforcement policy for apps targeting SDK versions prior to the latest
|
||||
* version.
|
||||
|
||||
@@ -166,6 +166,11 @@ class ZygoteConnection {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parsedArgs.hiddenApiAccessLogSampleRate != -1) {
|
||||
handleHiddenApiAccessLogSampleRate(parsedArgs.hiddenApiAccessLogSampleRate);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
|
||||
throw new ZygoteSecurityException("Client may not specify capabilities: " +
|
||||
"permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
|
||||
@@ -294,6 +299,15 @@ class ZygoteConnection {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleHiddenApiAccessLogSampleRate(int percent) {
|
||||
try {
|
||||
ZygoteInit.setHiddenApiAccessLogSampleRate(percent);
|
||||
mSocketOutStream.writeInt(0);
|
||||
} catch (IOException ioe) {
|
||||
throw new IllegalStateException("Error writing to command socket", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
protected void preload() {
|
||||
ZygoteInit.lazyPreload();
|
||||
}
|
||||
@@ -460,6 +474,12 @@ class ZygoteConnection {
|
||||
*/
|
||||
String[] apiBlacklistExemptions;
|
||||
|
||||
/**
|
||||
* Sampling rate for logging hidden API accesses to the event log. This is sent to the
|
||||
* pre-forked zygote at boot time, or when it changes, via --hidden-api-log-sampling-rate.
|
||||
*/
|
||||
int hiddenApiAccessLogSampleRate = -1;
|
||||
|
||||
/**
|
||||
* Constructs instance and parses args
|
||||
* @param args zygote command-line args
|
||||
@@ -483,6 +503,7 @@ class ZygoteConnection {
|
||||
|
||||
boolean seenRuntimeArgs = false;
|
||||
|
||||
boolean expectRuntimeArgs = true;
|
||||
for ( /* curArg */ ; curArg < args.length; curArg++) {
|
||||
String arg = args[curArg];
|
||||
|
||||
@@ -612,6 +633,7 @@ class ZygoteConnection {
|
||||
preloadPackageCacheKey = args[++curArg];
|
||||
} else if (arg.equals("--preload-default")) {
|
||||
preloadDefault = true;
|
||||
expectRuntimeArgs = false;
|
||||
} else if (arg.equals("--start-child-zygote")) {
|
||||
startChildZygote = true;
|
||||
} else if (arg.equals("--set-api-blacklist-exemptions")) {
|
||||
@@ -619,6 +641,16 @@ class ZygoteConnection {
|
||||
// with the regular fork command.
|
||||
apiBlacklistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
|
||||
curArg = args.length;
|
||||
expectRuntimeArgs = false;
|
||||
} else if (arg.startsWith("--hidden-api-log-sampling-rate=")) {
|
||||
String rateStr = arg.substring(arg.indexOf('=') + 1);
|
||||
try {
|
||||
hiddenApiAccessLogSampleRate = Integer.parseInt(rateStr);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid log sampling rate: " + rateStr, nfe);
|
||||
}
|
||||
expectRuntimeArgs = false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -633,7 +665,7 @@ class ZygoteConnection {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected arguments after --preload-package.");
|
||||
}
|
||||
} else if (!preloadDefault && apiBlacklistExemptions == null) {
|
||||
} else if (expectRuntimeArgs) {
|
||||
if (!seenRuntimeArgs) {
|
||||
throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ import android.icu.text.DecimalFormatSymbols;
|
||||
import android.icu.util.ULocale;
|
||||
import android.opengl.EGL14;
|
||||
import android.os.Build;
|
||||
import android.os.IInstalld;
|
||||
import android.os.Environment;
|
||||
import android.os.IInstalld;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
@@ -44,16 +44,16 @@ import android.system.OsConstants;
|
||||
import android.system.StructCapUserData;
|
||||
import android.system.StructCapUserHeader;
|
||||
import android.text.Hyphenator;
|
||||
import android.util.TimingsTraceLog;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.TimingsTraceLog;
|
||||
import android.webkit.WebViewFactory;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import dalvik.system.DexFile;
|
||||
import dalvik.system.VMRuntime;
|
||||
import dalvik.system.ZygoteHooks;
|
||||
@@ -67,8 +67,8 @@ import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.Security;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
|
||||
/**
|
||||
* Startup class for the zygote process.
|
||||
@@ -518,6 +518,10 @@ public class ZygoteInit {
|
||||
VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
|
||||
}
|
||||
|
||||
public static void setHiddenApiAccessLogSampleRate(int percent) {
|
||||
VMRuntime.getRuntime().setHiddenApiAccessLogSamplingRate(percent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PathClassLoader for the given class path that is associated with a shared
|
||||
* namespace, i.e., this classloader can access platform-private native libraries. The
|
||||
|
||||
@@ -246,6 +246,7 @@ public class SettingsBackupTest {
|
||||
Settings.Global.HDMI_CONTROL_ENABLED,
|
||||
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
|
||||
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
|
||||
Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE,
|
||||
Settings.Global.HIDDEN_API_POLICY_P_APPS,
|
||||
Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS,
|
||||
Settings.Global.HIDE_ERROR_DIALOGS,
|
||||
|
||||
@@ -2902,6 +2902,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
private boolean mBlacklistDisabled;
|
||||
private String mExemptionsStr;
|
||||
private List<String> mExemptions = Collections.emptyList();
|
||||
private int mLogSampleRate = -1;
|
||||
@HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
|
||||
@HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
|
||||
|
||||
@@ -2915,6 +2916,10 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
|
||||
false,
|
||||
this);
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
|
||||
false,
|
||||
this);
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
|
||||
false,
|
||||
@@ -2942,6 +2947,15 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
zygoteProcess.setApiBlacklistExemptions(mExemptions);
|
||||
}
|
||||
int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
|
||||
if (logSampleRate < 0 || logSampleRate > 0x10000) {
|
||||
logSampleRate = -1;
|
||||
}
|
||||
if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
|
||||
mLogSampleRate = logSampleRate;
|
||||
zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
|
||||
}
|
||||
mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
|
||||
mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user