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

Commit c095882f authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Exclude Telephony Binder interfaces.

Purposefully exclude telephony Binder interfaces, since we know they
always run under the separate AID_RADIO.

Bug: 155703208
Test: atest error_prone_android_framework_test
Change-Id: I3ce87caeb2abe3a7ca01ce10560d02b499ece07d
parent 31b3d88a
Loading
Loading
Loading
Loading
+41 −10
Original line number Diff line number Diff line
@@ -17,11 +17,14 @@
package com.google.errorprone.bugpatterns.android;

import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.matchers.Matchers.allOf;
import static com.google.errorprone.matchers.Matchers.contains;
import static com.google.errorprone.matchers.Matchers.enclosingClass;
import static com.google.errorprone.matchers.Matchers.hasAnnotation;
import static com.google.errorprone.matchers.Matchers.instanceMethod;
import static com.google.errorprone.matchers.Matchers.isSameType;
import static com.google.errorprone.matchers.Matchers.methodInvocation;
import static com.google.errorprone.matchers.Matchers.not;
import static com.google.errorprone.matchers.Matchers.throwStatement;
import static com.google.errorprone.matchers.Matchers.variableType;

@@ -29,13 +32,17 @@ import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.CatchTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.TryTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.predicates.TypePredicate;
import com.sun.source.tree.CatchTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TryTree;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.code.Type;

import java.util.List;

@@ -54,9 +61,17 @@ import java.util.List;
    name = "AndroidFrameworkRethrowFromSystem",
    summary = "Verifies that system_server calls use rethrowFromSystemServer()",
    severity = WARNING)
public final class RethrowFromSystemChecker extends BugChecker implements CatchTreeMatcher {
public final class RethrowFromSystemChecker extends BugChecker implements TryTreeMatcher {
    private static final Matcher<Tree> INSIDE_MANAGER =
            enclosingClass(hasAnnotation("android.annotation.SystemService"));

    // Purposefully exclude telephony Binder interfaces, since we know they
    // always run under the separate AID_RADIO
    private static final Matcher<ExpressionTree> SYSTEM_BINDER_CALL = methodInvocation(allOf(
            instanceMethod().onDescendantOf("android.os.IInterface").withAnyName(),
            not(instanceMethod().onClass(inPackage("com.android.internal.telephony"))),
            not(instanceMethod().onClass(inPackage("com.android.internal.telecom")))));

    private static final Matcher<VariableTree> REMOTE_EXCEPTION = variableType(
            isSameType("android.os.RemoteException"));
    private static final Matcher<StatementTree> RETHROW_FROM_SYSTEM = throwStatement(
@@ -64,17 +79,33 @@ public final class RethrowFromSystemChecker extends BugChecker implements CatchT
                    .named("rethrowFromSystemServer")));

    @Override
    public Description matchCatch(CatchTree tree, VisitorState state) {
    public Description matchTry(TryTree tree, VisitorState state) {
        if (INSIDE_MANAGER.matches(tree, state)
                && REMOTE_EXCEPTION.matches(tree.getParameter(), state)) {
            final List<? extends StatementTree> statements = tree.getBlock().getStatements();
            if (statements.size() != 1 || !RETHROW_FROM_SYSTEM.matches(statements.get(0), state)) {
                return buildDescription(tree)
                && contains(ExpressionTree.class, SYSTEM_BINDER_CALL)
                        .matches(tree.getBlock(), state)) {
            for (CatchTree catchTree : tree.getCatches()) {
                if (REMOTE_EXCEPTION.matches(catchTree.getParameter(), state)) {
                    final List<? extends StatementTree> statements = catchTree.getBlock()
                            .getStatements();
                    if (statements.size() != 1
                            || !RETHROW_FROM_SYSTEM.matches(statements.get(0), state)) {
                        return buildDescription(catchTree)
                                .setMessage("Must contain single "
                                        + "'throw e.rethrowFromSystemServer()' statement")
                                .build();
                    }
                }
            }
        }
        return Description.NO_MATCH;
    }

    private static TypePredicate inPackage(final String filter) {
        return new TypePredicate() {
            @Override
            public boolean apply(Type type, VisitorState state) {
                return type.tsym.packge().fullname.toString().startsWith(filter);
            }
        };
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -105,4 +105,27 @@ public class RethrowFromSystemCheckerTest {
                        "}")
                .doTest();
    }

    @Test
    public void testTelephony() {
        compilationHelper
                .addSourceFile("/android/annotation/SystemService.java")
                .addSourceFile("/com/android/internal/telephony/ITelephony.java")
                .addSourceFile("/android/os/IInterface.java")
                .addSourceFile("/android/os/RemoteException.java")
                .addSourceLines("TelephonyManager.java",
                        "import android.annotation.SystemService;",
                        "import com.android.internal.telephony.ITelephony;",
                        "import android.os.RemoteException;",
                        "@SystemService(\"telephony\") public class TelephonyManager {",
                        "  ITelephony mService;",
                        "  void bar() {",
                        "    try {",
                        "      mService.bar();",
                        "    } catch (RemoteException ignored) {",
                        "    }",
                        "  }",
                        "}")
                .doTest();
    }
}
+23 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.internal.telephony;

import android.os.RemoteException;

public interface ITelephony extends android.os.IInterface {
    public void bar() throws RemoteException;
}