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

Commit 2ccd4a1f authored by twyen's avatar twyen Committed by Copybara-Service
Browse files

Implement blocking commands

Test: Unit tests
PiperOrigin-RevId: 182813080
Change-Id: I952f49352fb57c02c4efb9cc4ede84dc7c32c893
parent e5a20898
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.support.annotation.VisibleForTesting;
import android.telecom.TelecomManager;
import android.telephony.PhoneNumberUtils;
import com.android.dialer.common.LogUtil;
import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.database.FilteredNumberContract.FilteredNumber;
import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns;
import com.android.dialer.database.FilteredNumberContract.FilteredNumberSources;
@@ -117,7 +118,9 @@ public class FilteredNumberCompat {
   *     migration has been performed, {@code false} otherwise.
   */
  public static boolean useNewFiltering(Context context) {
    return canUseNewFiltering() && hasMigratedToNewBlocking(context);
    return !ConfigProviderBindings.get(context).getBoolean("debug_force_dialer_filtering", false)
        && canUseNewFiltering()
        && hasMigratedToNewBlocking(context);
  }

  /**
+144 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.dialer.commandline;

import android.support.annotation.Nullable;
import com.android.dialer.commandline.Command.IllegalCommandLineArgumentException;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import com.google.common.collect.UnmodifiableIterator;

/**
 * Parses command line arguments into optional flags (--foo, --key=value, --key value) and required
 * positionals (which must be passed in order). Flags must start with "--" and are always before
 * positionals. If flags are used "--" must be placed before positionals.
 *
 * <p>--flag will be interpreted as --flag=true, and --noflag as --flag=false
 *
 * <p>Grammar:<br>
 * dialer-cmd.py <cmd> <args><br>
 * <args> = (<flags> -- <positionals>) | <positionals><br>
 * <flags> = "no"?<name>(<separator><value>)?<br>
 * <separator> = " " | "="
 */
@AutoValue
public abstract class Arguments {

  public static final Arguments EMPTY =
      new AutoValue_Arguments(ImmutableMap.of(), ImmutableList.of());

  public abstract ImmutableMap<String, String> getFlags();

  public abstract ImmutableList<String> getPositionals();

  /**
   * Return the positional at {@code position}. Throw {@link IllegalCommandLineArgumentException} if
   * it is absent and reports to the user {@code name} is expected.
   */
  public String expectPositional(int position, String name)
      throws IllegalCommandLineArgumentException {
    if (getPositionals().size() <= position) {
      throw new IllegalCommandLineArgumentException(name + " expected");
    }
    return getPositionals().get(position);
  }

  public Boolean getBoolean(String flag, boolean defaultValue)
      throws IllegalCommandLineArgumentException {
    if (!getFlags().containsKey(flag)) {
      return defaultValue;
    }
    switch (getFlags().get(flag)) {
      case "true":
        return true;
      case "false":
        return false;
      default:
        throw new IllegalCommandLineArgumentException("boolean value expected for " + flag);
    }
  }

  public static Arguments parse(@Nullable String[] rawArguments)
      throws IllegalCommandLineArgumentException {
    if (rawArguments == null) {
      return EMPTY;
    }
    return parse(Iterators.forArray(rawArguments));
  }

  public static Arguments parse(Iterable<String> rawArguments)
      throws IllegalCommandLineArgumentException {
    return parse(Iterators.unmodifiableIterator(rawArguments.iterator()));
  }

  public static Arguments parse(UnmodifiableIterator<String> iterator)
      throws IllegalCommandLineArgumentException {
    PeekingIterator<String> peekingIterator = Iterators.peekingIterator(iterator);
    ImmutableMap<String, String> flags = parseFlags(peekingIterator);
    ImmutableList<String> positionals = parsePositionals(peekingIterator);

    return new AutoValue_Arguments(flags, positionals);
  }

  private static ImmutableMap<String, String> parseFlags(PeekingIterator<String> iterator)
      throws IllegalCommandLineArgumentException {
    ImmutableMap.Builder<String, String> flags = ImmutableMap.builder();
    if (!iterator.hasNext()) {
      return flags.build();
    }
    if (!iterator.peek().startsWith("--")) {
      return flags.build();
    }

    while (iterator.hasNext()) {
      String peek = iterator.peek();
      if (peek.equals("--")) {
        iterator.next();
        return flags.build();
      }
      if (peek.startsWith("--")) {
        String key = iterator.next().substring(2);
        String value;
        if (iterator.hasNext() && !iterator.peek().startsWith("--")) {
          value = iterator.next();
        } else if (key.contains("=")) {
          String[] entry = key.split("=", 2);
          key = entry[0];
          value = entry[1];
        } else if (key.startsWith("no")) {
          key = key.substring(2);
          value = "false";
        } else {
          value = "true";
        }
        flags.put(key, value);
      } else {
        throw new IllegalCommandLineArgumentException("flag or '--' expected");
      }
    }
    return flags.build();
  }

  private static ImmutableList<String> parsePositionals(PeekingIterator<String> iterator) {
    ImmutableList.Builder<String> positionals = ImmutableList.builder();
    positionals.addAll(iterator);
    return positionals.build();
  }
}
+18 −2
Original line number Diff line number Diff line
@@ -17,15 +17,31 @@
package com.android.dialer.commandline;

import android.support.annotation.NonNull;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;

/** Handles a Command from {@link CommandLineReceiver}. */
public interface Command {

  ListenableFuture<String> run(ImmutableList<String> args);
  /**
   * Thrown when {@code args} in {@link #run(Arguments)} does not match the expected format. The
   * commandline will print {@code message} and {@link #getUsage()}.
   */
  class IllegalCommandLineArgumentException extends Exception {
    public IllegalCommandLineArgumentException(String message) {
      super(message);
    }
  }

  /** Describe the command when "help" is listing available commands. */
  @NonNull
  String getShortDescription();

  /**
   * Call when 'command --help' is called or when {@link IllegalCommandLineArgumentException} is
   * thrown to inform the user how should the command be used.
   */
  @NonNull
  String getUsage();

  ListenableFuture<String> run(Arguments args) throws IllegalCommandLineArgumentException;
}
+5 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.dialer.commandline;

import com.android.dialer.commandline.impl.Blocking;
import com.android.dialer.commandline.impl.Echo;
import com.android.dialer.commandline.impl.Help;
import com.android.dialer.commandline.impl.Version;
@@ -41,18 +42,21 @@ public abstract class CommandLineModule {
    private final Help help;
    private final Version version;
    private final Echo echo;
    private final Blocking blocking;

    @Inject
    AospCommandInjector(Help help, Version version, Echo echo) {
    AospCommandInjector(Help help, Version version, Echo echo, Blocking blocking) {
      this.help = help;
      this.version = version;
      this.echo = echo;
      this.blocking = blocking;
    }

    public CommandSupplier.Builder inject(CommandSupplier.Builder builder) {
      builder.addCommand("help", help);
      builder.addCommand("version", version);
      builder.addCommand("echo", echo);
      builder.addCommand("blocking", blocking);
      return builder;
    }
  }
+16 −12
Original line number Diff line number Diff line
@@ -21,8 +21,8 @@ import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.android.dialer.buildtype.BuildType;
import com.android.dialer.commandline.Command.IllegalCommandLineArgumentException;
import com.android.dialer.common.LogUtil;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
@@ -53,17 +53,18 @@ public class CommandLineReceiver extends BroadcastReceiver {
            .commandSupplier()
            .get()
            .get(intent.getStringExtra(COMMAND));
    try {
      if (command == null) {
        LogUtil.i(outputTag, "unknown command " + intent.getStringExtra(COMMAND));
        return;
      }

    ImmutableList<String> args =
        intent.hasExtra(ARGS)
            ? ImmutableList.copyOf(intent.getStringArrayExtra(ARGS))
            : ImmutableList.of();
      Arguments args = Arguments.parse(intent.getStringArrayExtra(ARGS));

    try {
      if (args.getBoolean("help", false)) {
        LogUtil.i(outputTag, "usage:\n" + command.getUsage());
        return;
      }
      Futures.addCallback(
          command.run(args),
          new FutureCallback<String>() {
@@ -78,12 +79,15 @@ public class CommandLineReceiver extends BroadcastReceiver {

            @Override
            public void onFailure(Throwable throwable) {
              // LogUtil.e(tag, message, e) prints 2 entries where only the first one can be
              // intercepted by the script. Compose the string instead.
              if (throwable instanceof IllegalCommandLineArgumentException) {
                LogUtil.e(outputTag, throwable.getMessage() + "\n\nusage:\n" + command.getUsage());
              }
              LogUtil.e(outputTag, "error running command future", throwable);
            }
          },
          MoreExecutors.directExecutor());
    } catch (IllegalCommandLineArgumentException e) {
      LogUtil.e(outputTag, e.getMessage() + "\n\nusage:\n" + command.getUsage());
    } catch (Throwable throwable) {
      LogUtil.e(outputTag, "error running command", throwable);
    }
Loading