Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b7fd29f authored by Stanislav Zholnin's avatar Stanislav Zholnin Committed by Android (Google) Code Review
Browse files

Merge "Stack Trace sampling and reporting."

parents 9a5d3ad5 90516b92
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -6426,9 +6426,13 @@ package android.app {
  public class StatusBarManager {
  }
  public final class SyncNotedAppOp {
  public final class SyncNotedAppOp implements android.os.Parcelable {
    ctor public SyncNotedAppOp(@IntRange(from=0L) int, @Nullable String);
    method public int describeContents();
    method @Nullable public String getFeatureId();
    method @NonNull public String getOp();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.SyncNotedAppOp> CREATOR;
  }
  @Deprecated public class TabActivity extends android.app.ActivityGroup {
+14 −0
Original line number Diff line number Diff line
@@ -365,6 +365,7 @@ package android.app {
  }
  public class AppOpsManager {
    method @Nullable @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public android.app.RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage();
    method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
    method public static String[] getOpStrs();
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
@@ -681,6 +682,19 @@ package android.app {
    method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean);
  }
  public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
    ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
    method public int describeContents();
    method @Nullable public String getFeatureId();
    method @NonNull public String getMessage();
    method @NonNull public String getOp();
    method @NonNull public String getPackageName();
    method public int getSamplingStrategy();
    method @IntRange(from=0L) public int getUid();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.RuntimeAppOpAccessMessage> CREATOR;
  }
  public class SearchManager implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
    method public void launchAssist(@Nullable android.os.Bundle);
  }
+14 −0
Original line number Diff line number Diff line
@@ -164,6 +164,7 @@ package android.app {
  public class AppOpsManager {
    method @RequiresPermission("android.permission.MANAGE_APPOPS") public void addHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOps);
    method @RequiresPermission("android.permission.MANAGE_APPOPS") public void clearHistory();
    method @Nullable @RequiresPermission("android.permission.GET_APP_OPS_STATS") public android.app.RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage();
    method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
    method @RequiresPermission("android.permission.MANAGE_APPOPS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
    method public static int getNumOps();
@@ -447,6 +448,19 @@ package android.app {
    method public android.graphics.Rect getSourceRectHint();
  }

  public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
    ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
    method public int describeContents();
    method @Nullable public String getFeatureId();
    method @NonNull public String getMessage();
    method @NonNull public String getOp();
    method @NonNull public String getPackageName();
    method public int getSamplingStrategy();
    method @IntRange(from=0L) public int getUid();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.RuntimeAppOpAccessMessage> CREATOR;
  }

  public class StatusBarManager {
    method public void collapsePanels();
    method public void expandNotificationsPanel();
+119 −3
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package android.app;

import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT;
import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;

import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -48,6 +52,8 @@ import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -63,6 +69,7 @@ import com.android.internal.app.IAppOpsAsyncNotedCallback;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsNotedCallback;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.MessageSamplingConfig;
import com.android.internal.os.RuntimeInit;
import com.android.internal.os.ZygoteInit;
import com.android.internal.util.ArrayUtils;
@@ -141,6 +148,13 @@ public class AppOpsManager {
    @UnsupportedAppUsage
    final IAppOpsService mService;

    /**
     * Service for the application context, to be used by static methods via
     * {@link #getService()}
     */
    @GuardedBy("sLock")
    static IAppOpsService sService;

    @GuardedBy("mModeWatchers")
    private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
            new ArrayMap<>();
@@ -159,6 +173,50 @@ public class AppOpsManager {
    @GuardedBy("sLock")
    private static @Nullable AppOpsCollector sNotedAppOpsCollector;

    /**
     * Additional collector that collect accesses and forwards a few of them them via
     * {@link IAppOpsService#reportRuntimeAppOpAccessMessageAndGetConfig}.
     */
    private static AppOpsCollector sMessageCollector =
            new AppOpsCollector() {
                @Override
                public void onNoted(@NonNull SyncNotedAppOp op) {
                    reportStackTraceIfNeeded(op);
                }

                @Override
                public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp) {
                    // collected directly in AppOpsService
                }

                @Override
                public void onSelfNoted(@NonNull SyncNotedAppOp op) {
                    reportStackTraceIfNeeded(op);
                }

                private void reportStackTraceIfNeeded(@NonNull SyncNotedAppOp op) {
                    if (sConfig.getSampledOpCode() == OP_NONE
                            && sConfig.getExpirationTimeSinceBootMillis()
                            >= SystemClock.elapsedRealtime()) {
                        return;
                    }

                    MessageSamplingConfig config = sConfig;
                    if (leftCircularDistance(strOpToOp(op.getOp()), config.getSampledOpCode(),
                            _NUM_OP) <= config.getAcceptableLeftDistance()
                            || config.getExpirationTimeSinceBootMillis()
                            < SystemClock.elapsedRealtime()) {
                        String stackTrace = getFormattedStackTrace();
                        try {
                            sConfig = getService().reportRuntimeAppOpAccessMessageAndGetConfig(
                                    ActivityThread.currentOpPackageName(), op, stackTrace);
                        } catch (RemoteException e) {
                            e.rethrowFromSystemServer();
                        }
                    }
                }
            };

    static IBinder sClientId;

    /**
@@ -550,7 +608,6 @@ public class AppOpsManager {
    })
    public @interface OpFlags {}


    /** @hide */
    public static final String getFlagName(@OpFlags int flag) {
        switch (flag) {
@@ -569,6 +626,18 @@ public class AppOpsManager {
        }
    }

    /**
     * Strategies used for message sampling
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"RUNTIME_APP_OPS_ACCESS__SAMPLING_STRATEGY__"}, value = {
            RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT,
            RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM,
            RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED
    })
    public @interface SamplingStrategy {}

    private static final int UID_STATE_OFFSET = 31;
    private static final int FLAGS_MASK = 0xFFFFFFFF;

@@ -2225,6 +2294,10 @@ public class AppOpsManager {
        }
    }

    /** Config used to control app ops access messages sampling */
    private static MessageSamplingConfig sConfig =
            new MessageSamplingConfig(OP_NONE, 0, 0);

    /** @hide */
    public static final String KEY_HISTORICAL_OPS = "historical_ops";

@@ -7268,6 +7341,17 @@ public class AppOpsManager {
        }
    }

    /** @hide */
    private static IAppOpsService getService() {
        synchronized (sLock) {
            if (sService == null) {
                sService = IAppOpsService.Stub.asInterface(
                        ServiceManager.getService(Context.APP_OPS_SERVICE));
            }
            return sService;
        }
    }

    /**
     * @deprecated use {@link #startOp(String, int, String, String, String)} instead
     */
@@ -7614,6 +7698,7 @@ public class AppOpsManager {
                sNotedAppOpsCollector.onSelfNoted(new SyncNotedAppOp(op, featureId));
            }
        }
        sMessageCollector.onSelfNoted(new SyncNotedAppOp(op, featureId));
    }

    /**
@@ -7764,6 +7849,10 @@ public class AppOpsManager {
                        }
                    }
                }
                for (int code = notedAppOps.nextSetBit(0); code != -1;
                        code = notedAppOps.nextSetBit(code + 1)) {
                    sMessageCollector.onNoted(new SyncNotedAppOp(code, featureId));
                }
            }
        }
    }
@@ -7958,10 +8047,13 @@ public class AppOpsManager {

        StringBuilder sb = new StringBuilder();
        for (int i = firstInteresting; i <= lastInteresting; i++) {
            sb.append(trace[i]);
            if (i != lastInteresting) {
            if (i != firstInteresting) {
                sb.append('\n');
            }
            if (sb.length() + trace[i].toString().length() > 600) {
                break;
            }
            sb.append(trace[i]);
        }

        return sb.toString();
@@ -8088,6 +8180,22 @@ public class AppOpsManager {
        }
    }

    /**
     * Pulls current AppOps access report and picks package and op to watch for next access report
     *
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
    public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() {
        try {
            return mService.collectRuntimeAppOpAccessMessage();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns all supported operation names.
     * @hide
@@ -8297,4 +8405,12 @@ public class AppOpsManager {

        return AppOpsManager.MODE_DEFAULT;
    }

    /**
     * Calculate left circular distance for two numbers modulo size.
     * @hide
     */
    public static int leftCircularDistance(int from, int to, int size) {
        return (to + size - from) % size;
    }
}
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 android.app;

parcelable RuntimeAppOpAccessMessage;
Loading