Ejemplo n.º 1
0
  @Override
  public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mAcceptButton = (Button) view.findViewById(R.id.terms_accept);
    mSendReportCheckBox = (CheckBox) view.findViewById(R.id.send_report_checkbox);
    mTosAndPrivacy = (TextView) view.findViewById(R.id.tos_and_privacy);

    mAcceptButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            getPageDelegate().acceptTermsOfService(mSendReportCheckBox.isChecked());
          }
        });

    if (ChromeVersionInfo.isOfficialBuild()) {
      int paddingStart = getResources().getDimensionPixelSize(R.dimen.fre_tos_checkbox_padding);
      ApiCompatibilityUtils.setPaddingRelative(
          mSendReportCheckBox,
          ApiCompatibilityUtils.getPaddingStart(mSendReportCheckBox) + paddingStart,
          mSendReportCheckBox.getPaddingTop(),
          ApiCompatibilityUtils.getPaddingEnd(mSendReportCheckBox),
          mSendReportCheckBox.getPaddingBottom());

      mSendReportCheckBox.setChecked(FirstRunActivity.DEFAULT_METRICS_AND_CRASH_REPORTING);
    } else {
      mSendReportCheckBox.setVisibility(View.GONE);
    }

    mTosAndPrivacy.setMovementMethod(LinkMovementMethod.getInstance());

    NoUnderlineClickableSpan clickableTermsSpan =
        new NoUnderlineClickableSpan() {
          @Override
          public void onClick(View widget) {
            if (!isAdded()) return;
            getPageDelegate()
                .showEmbedContentViewActivity(
                    R.string.terms_of_service_title, R.string.chrome_terms_of_service_url);
          }
        };

    NoUnderlineClickableSpan clickablePrivacySpan =
        new NoUnderlineClickableSpan() {
          @Override
          public void onClick(View widget) {
            if (!isAdded()) return;
            getPageDelegate()
                .showEmbedContentViewActivity(
                    R.string.privacy_notice_title, R.string.chrome_privacy_notice_url);
          }
        };
    mTosAndPrivacy.setText(
        SpanApplier.applySpans(
            getString(R.string.fre_tos_and_privacy),
            new SpanInfo("<LINK1>", "</LINK1>", clickableTermsSpan),
            new SpanInfo("<LINK2>", "</LINK2>", clickablePrivacySpan)));
  }
Ejemplo n.º 2
0
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    WebappInfo webappInfo = WebappInfo.create(intent);
    String webappId = webappInfo.id();
    String webappUrl = webappInfo.uri().toString();
    int webappSource = webappInfo.source();

    if (webappId != null && webappUrl != null) {
      String webappMacString = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_MAC);
      byte[] webappMac =
          webappMacString == null ? null : Base64.decode(webappMacString, Base64.DEFAULT);

      Intent launchIntent = null;
      if (webappMac != null && WebappAuthenticator.isUrlValid(this, webappUrl, webappMac)) {
        LaunchMetrics.recordHomeScreenLaunchIntoStandaloneActivity(webappUrl, webappSource);

        String activityName = WebappActivity.class.getName();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
          // Specifically assign the app to a particular WebappActivity instance.
          int activityIndex = ActivityAssigner.instance(this).assign(webappId);
          activityName += String.valueOf(activityIndex);
        }

        // Create an intent to launch the Webapp in an unmapped WebappActivity.
        launchIntent = new Intent();
        launchIntent.setClassName(this, activityName);
        webappInfo.setWebappIntentExtras(launchIntent);

        // On L+, firing intents with the exact same data should relaunch a particular
        // Activity.
        launchIntent.setAction(Intent.ACTION_VIEW);
        launchIntent.setData(Uri.parse(WebappActivity.WEBAPP_SCHEME + "://" + webappId));
      } else {
        Log.e(TAG, "Shortcut (" + webappUrl + ") opened in Chrome.");

        // The shortcut data doesn't match the current encoding.  Change the intent action
        // launch the URL with a VIEW Intent in the regular browser.
        launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(webappUrl));
        launchIntent.setClassName(getPackageName(), ChromeLauncherActivity.class.getName());
        launchIntent.putExtra(ShortcutHelper.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true);
        launchIntent.putExtra(ShortcutHelper.EXTRA_SOURCE, webappSource);
      }

      launchIntent.setFlags(
          Intent.FLAG_ACTIVITY_NEW_TASK | ApiCompatibilityUtils.getActivityNewDocumentFlag());
      startActivity(launchIntent);
    }

    ApiCompatibilityUtils.finishAndRemoveTask(this);
  }
  @Override
  public void updateVisualsForState() {
    Resources resources = getResources();
    updateSecurityIcon(getSecurityLevel());
    ColorStateList colorStateList =
        resources.getColorStateList(
            mUseDarkColors ? R.color.dark_mode_tint : R.color.light_mode_tint);
    mMenuButton.setTint(colorStateList);
    if (mCloseButton.getDrawable() instanceof TintedDrawable) {
      ((TintedDrawable) mCloseButton.getDrawable()).setTint(colorStateList);
    }
    if (mCustomActionButton.getDrawable() instanceof TintedDrawable) {
      ((TintedDrawable) mCustomActionButton.getDrawable()).setTint(colorStateList);
    }
    mUrlBar.setUseDarkTextColors(mUseDarkColors);

    int titleTextColor =
        mUseDarkColors
            ? resources.getColor(R.color.url_emphasis_default_text)
            : resources.getColor(R.color.url_emphasis_light_default_text);
    mTitleBar.setTextColor(titleTextColor);

    if (getProgressBar() != null) {
      int progressBarResource =
          !mUseDarkColors ? R.drawable.progress_bar_white : R.drawable.progress_bar;
      getProgressBar()
          .setProgressDrawable(
              ApiCompatibilityUtils.getDrawable(getResources(), progressBarResource));
    }
  }
  /**
   * Creates a standard toggle switch and adds it to the layout.
   *
   * <p>------------------------------------------------- | ICON | MESSAGE | TOGGLE |
   * ------------------------------------------------- If an icon is not provided, the ImageView
   * that would normally show it is hidden.
   *
   * @param iconResourceId ID of the drawable to use for the icon, or 0 to hide the ImageView.
   * @param iconColorId ID of the tint color for the icon, or 0 for default.
   * @param toggleMessage Message to display for the toggle.
   * @param toggleId ID to use for the toggle.
   * @param isChecked Whether the toggle should start off checked.
   */
  public View addSwitch(
      int iconResourceId,
      int iconColorId,
      CharSequence toggleMessage,
      int toggleId,
      boolean isChecked) {
    LinearLayout switchLayout =
        (LinearLayout)
            LayoutInflater.from(getContext()).inflate(R.layout.infobar_control_toggle, this, false);
    addView(switchLayout, new ControlLayoutParams());

    ImageView iconView = (ImageView) switchLayout.findViewById(R.id.control_icon);
    if (iconResourceId == 0) {
      switchLayout.removeView(iconView);
    } else {
      iconView.setImageResource(iconResourceId);
      if (iconColorId != 0) {
        iconView.setColorFilter(ApiCompatibilityUtils.getColor(getResources(), iconColorId));
      }
    }

    TextView messageView = (TextView) switchLayout.findViewById(R.id.control_message);
    messageView.setText(toggleMessage);

    SwitchCompat switchView = (SwitchCompat) switchLayout.findViewById(R.id.control_toggle_switch);
    switchView.setId(toggleId);
    switchView.setChecked(isChecked);

    return switchLayout;
  }
  /**
   * Adds an icon with a descriptive message to the layout.
   *
   * <p>----------------------------------------------------- | ICON | PRIMARY MESSAGE SECONDARY
   * MESSAGE | ----------------------------------------------------- If an icon is not provided, the
   * ImageView that would normally show it is hidden.
   *
   * @param iconResourceId ID of the drawable to use for the icon.
   * @param iconColorId ID of the tint color for the icon, or 0 for default.
   * @param primaryMessage Message to display for the toggle.
   * @param secondaryMessage Additional descriptive text for the toggle. May be null.
   */
  public View addIcon(
      int iconResourceId,
      int iconColorId,
      CharSequence primaryMessage,
      CharSequence secondaryMessage) {
    LinearLayout layout =
        (LinearLayout)
            LayoutInflater.from(getContext())
                .inflate(R.layout.infobar_control_icon_with_description, this, false);
    addView(layout, new ControlLayoutParams());

    ImageView iconView = (ImageView) layout.findViewById(R.id.control_icon);
    iconView.setImageResource(iconResourceId);
    if (iconColorId != 0) {
      iconView.setColorFilter(ApiCompatibilityUtils.getColor(getResources(), iconColorId));
    }

    // The primary message text is always displayed.
    TextView primaryView = (TextView) layout.findViewById(R.id.control_message);
    primaryView.setText(primaryMessage);

    // The secondary message text is optional.
    TextView secondaryView = (TextView) layout.findViewById(R.id.control_secondary_message);
    if (secondaryMessage == null) {
      layout.removeView(secondaryView);
    } else {
      secondaryView.setText(secondaryMessage);
    }

    return layout;
  }
Ejemplo n.º 6
0
  /**
   * Adds one, two, or three buttons to the layout.
   *
   * @param primaryText Text for the primary button.
   * @param secondaryText Text for the secondary button, or null if there isn't a second button.
   * @param tertiaryText Text for the tertiary button, or null if there isn't a third button.
   */
  public void setButtons(String primaryText, String secondaryText, String tertiaryText) {
    if (TextUtils.isEmpty(primaryText)) return;

    mPrimaryButton = new ButtonCompat(getContext(), mAccentColor);
    mPrimaryButton.setId(R.id.button_primary);
    mPrimaryButton.setOnClickListener(this);
    mPrimaryButton.setText(primaryText);
    mPrimaryButton.setTextColor(Color.WHITE);

    if (TextUtils.isEmpty(secondaryText)) return;

    mSecondaryButton = ButtonCompat.createBorderlessButton(getContext());
    mSecondaryButton.setId(R.id.button_secondary);
    mSecondaryButton.setOnClickListener(this);
    mSecondaryButton.setText(secondaryText);
    mSecondaryButton.setTextColor(mAccentColor);

    if (TextUtils.isEmpty(tertiaryText)) return;

    mTertiaryButton = ButtonCompat.createBorderlessButton(getContext());
    mTertiaryButton.setId(R.id.button_tertiary);
    mTertiaryButton.setOnClickListener(this);
    mTertiaryButton.setText(tertiaryText);
    mTertiaryButton.setPadding(
        mMargin / 2,
        mTertiaryButton.getPaddingTop(),
        mMargin / 2,
        mTertiaryButton.getPaddingBottom());
    mTertiaryButton.setTextColor(
        ApiCompatibilityUtils.getColor(
            getContext().getResources(), R.color.infobar_tertiary_button_text));
  }
Ejemplo n.º 7
0
  /**
   * Checks if the First Run needs to be launched.
   *
   * @return The intent to launch the First Run Experience if necessary, or null.
   * @param context The context.
   * @param fromIntent The intent that was used to launch Chrome.
   * @param forLightweightFre Whether this is a check for the Lightweight First Run Experience.
   */
  public static Intent checkIfFirstRunIsNecessary(
      Context context, Intent fromIntent, boolean forLightweightFre) {
    // If FRE is disabled (e.g. in tests), proceed directly to the intent handling.
    if (CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
        || ApiCompatibilityUtils.isDemoUser(context)) {
      return null;
    }

    // If Chrome isn't opened via the Chrome icon, and the user accepted the ToS
    // in the Setup Wizard, skip any First Run Experience screens and proceed directly
    // to the intent handling.
    final boolean fromChromeIcon =
        fromIntent != null && TextUtils.equals(fromIntent.getAction(), Intent.ACTION_MAIN);
    if (!fromChromeIcon && ToSAckedReceiver.checkAnyUserHasSeenToS(context)) return null;

    final boolean baseFreComplete = FirstRunStatus.getFirstRunFlowComplete(context);
    if (!baseFreComplete) {
      if (forLightweightFre
          && CommandLine.getInstance()
              .hasSwitch(ChromeSwitches.ENABLE_LIGHTWEIGHT_FIRST_RUN_EXPERIENCE)) {
        if (!FirstRunStatus.shouldSkipWelcomePage(context)
            && !FirstRunStatus.getLightweightFirstRunFlowComplete(context)) {
          return createLightweightFirstRunIntent(context, fromChromeIcon);
        }
      } else {
        return createGenericFirstRunIntent(context, fromChromeIcon);
      }
    }

    // Promo pages are removed, so there is nothing else to show in FRE.
    return null;
  }
Ejemplo n.º 8
0
  /**
   * Constructs a layout for the specified InfoBar. After calling this, be sure to set the message,
   * the buttons, and/or the custom content using setMessage(), setButtons(), and
   * setCustomContent().
   *
   * @param context The context used to render.
   * @param infoBarView InfoBarView that listens to events.
   * @param iconResourceId ID of the icon to use for the InfoBar.
   * @param iconBitmap Bitmap for the icon to use, if the resource ID wasn't passed through.
   * @param message The message to show in the infobar.
   */
  public InfoBarLayout(
      Context context,
      InfoBarView infoBarView,
      int iconResourceId,
      Bitmap iconBitmap,
      CharSequence message) {
    super(context);
    mInfoBarView = infoBarView;

    // Grab the dimensions.
    Resources res = getResources();
    mMargin = res.getDimensionPixelOffset(R.dimen.infobar_margin);
    mIconSize = res.getDimensionPixelSize(R.dimen.infobar_icon_size);
    mMinWidth = res.getDimensionPixelSize(R.dimen.infobar_min_width);
    mAccentColor = ApiCompatibilityUtils.getColor(res, R.color.infobar_accent_blue);

    // Set up the close button. Apply padding so it has a big touch target.
    mCloseButton = new ImageButton(context);
    mCloseButton.setId(R.id.infobar_close_button);
    mCloseButton.setImageResource(R.drawable.btn_close);
    TypedArray a = getContext().obtainStyledAttributes(new int[] {R.attr.selectableItemBackground});
    Drawable closeButtonBackground = a.getDrawable(0);
    a.recycle();
    mCloseButton.setBackground(closeButtonBackground);
    mCloseButton.setPadding(mMargin, mMargin, mMargin, mMargin);
    mCloseButton.setOnClickListener(this);
    mCloseButton.setContentDescription(res.getString(R.string.infobar_close));
    mCloseButton.setLayoutParams(new LayoutParams(0, -mMargin, -mMargin, -mMargin));

    // Set up the icon.
    if (iconResourceId != 0 || iconBitmap != null) {
      mIconView = new ImageView(context);
      if (iconResourceId != 0) {
        mIconView.setImageResource(iconResourceId);
      } else if (iconBitmap != null) {
        mIconView.setImageBitmap(iconBitmap);
      }
      mIconView.setLayoutParams(new LayoutParams(0, 0, mMargin / 2, 0));
      mIconView.getLayoutParams().width = mIconSize;
      mIconView.getLayoutParams().height = mIconSize;
      mIconView.setFocusable(false);
    }

    // Set up the message view.
    mMessageTextView = (TextView) LayoutInflater.from(context).inflate(R.layout.infobar_text, null);
    mMessageTextView.setText(message, TextView.BufferType.SPANNABLE);
    mMessageTextView.setMovementMethod(LinkMovementMethod.getInstance());
    mMessageTextView.setLinkTextColor(mAccentColor);
    mMessageView = mMessageTextView;
  }
 /**
  * Displays Auto sign-in snackbar, which communicates to the users that they were signed in to the
  * web site.
  */
 @CalledByNative
 private static void showSnackbar(Tab tab, String text) {
   SnackbarManager snackbarManager = tab.getSnackbarManager();
   if (snackbarManager == null) return;
   AutoSigninSnackbarController snackbarController =
       new AutoSigninSnackbarController(snackbarManager, tab);
   Snackbar snackbar = Snackbar.make(text, snackbarController);
   Resources resources = tab.getWindowAndroid().getActivity().get().getResources();
   int backgroundColor =
       ApiCompatibilityUtils.getColor(
           resources, R.color.smart_lock_auto_signin_snackbar_background_color);
   Bitmap icon = BitmapFactory.decodeResource(resources, R.drawable.account_management_no_picture);
   snackbar.setSingleLine(false).setBackgroundColor(backgroundColor).setProfileImage(icon);
   snackbarManager.showSnackbar(snackbar);
 }
Ejemplo n.º 10
0
 @Override
 protected void updateBookmarkButton(boolean isBookmarked, boolean editingAllowed) {
   if (isBookmarked) {
     mBookmarkButton.setImageResource(R.drawable.btn_star_filled);
     // Non-incognito mode shows a blue filled star.
     mBookmarkButton.setTint(
         isIncognito()
             ? mLightModeTint
             : ApiCompatibilityUtils.getColorStateList(getResources(), R.color.blue_mode_tint));
   } else {
     mBookmarkButton.setImageResource(R.drawable.btn_star);
     mBookmarkButton.setTint(isIncognito() ? mLightModeTint : mDarkModeTint);
   }
   mBookmarkButton.setEnabled(editingAllowed);
 }
  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    int width = right - left;
    boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this);

    // Child positions were already determined during the measurement pass.
    for (int childIndex = 0; childIndex < getChildCount(); childIndex++) {
      View child = getChildAt(childIndex);
      int childLeft = getControlLayoutParams(child).start;
      if (isRtl) childLeft = width - childLeft - child.getMeasuredWidth();

      int childTop = getControlLayoutParams(child).top;
      int childRight = childLeft + child.getMeasuredWidth();
      int childBottom = childTop + child.getMeasuredHeight();
      child.layout(childLeft, childTop, childRight, childBottom);
    }
  }
Ejemplo n.º 12
0
  /** Starts determining parameters for the First Run. Once finished, calls onFlowIsKnown(). */
  public void start() {
    if (CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
        || ApiCompatibilityUtils.isDemoUser(mActivity)) {
      onFlowIsKnown(null);
      return;
    }

    if (!mLaunchProperties.getBoolean(FirstRunActivity.EXTRA_USE_FRE_FLOW_SEQUENCER)) {
      onFlowIsKnown(mLaunchProperties);
      return;
    }

    new AndroidEduAndChildAccountHelper() {
      @Override
      public void onParametersReady() {
        processFreEnvironment(isAndroidEduDevice(), hasChildAccount());
      }
    }.start(mActivity.getApplicationContext());
  }
Ejemplo n.º 13
0
  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    // Place all the views in the positions already determined during onMeasure().
    int width = right - left;
    boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this);

    for (int i = 0; i < getChildCount(); i++) {
      View child = getChildAt(i);
      LayoutParams lp = (LayoutParams) child.getLayoutParams();
      int childLeft = lp.start;
      int childRight = lp.start + child.getMeasuredWidth();

      if (isRtl) {
        int tmp = width - childRight;
        childRight = width - childLeft;
        childLeft = tmp;
      }

      child.layout(childLeft, lp.top, childRight, lp.top + child.getMeasuredHeight());
    }
  }
Ejemplo n.º 14
0
  /** Shows the work profile badge if it is needed. */
  private void addWorkProfileBadge(RemoteViews view) {
    Resources resources = mContext.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    int size = dpToPx(WORK_PROFILE_BADGE_SIZE_DP, metrics);
    int[] colors = new int[size * size];

    // Create an immutable bitmap, so that it can not be reused for painting a badge into it.
    Bitmap bitmap = Bitmap.createBitmap(colors, size, size, Bitmap.Config.ARGB_8888);

    Drawable inputDrawable = new BitmapDrawable(resources, bitmap);
    Drawable outputDrawable =
        ApiCompatibilityUtils.getUserBadgedDrawableForDensity(
            mContext, inputDrawable, null /* badgeLocation */, metrics.densityDpi);

    // The input bitmap is immutable, so the output drawable will be a different instance from
    // the input drawable if the work profile badge was applied.
    if (inputDrawable != outputDrawable && outputDrawable instanceof BitmapDrawable) {
      view.setImageViewBitmap(
          R.id.work_profile_badge, ((BitmapDrawable) outputDrawable).getBitmap());
      view.setViewVisibility(R.id.work_profile_badge, View.VISIBLE);
    }
  }
Ejemplo n.º 15
0
  /**
   * Creates an InterestsPage.
   *
   * @param context The view context for showing the page.
   * @param tab The tab from which interests page is loaded.
   * @param profile The profile from which to load interests.
   */
  public InterestsPage(final Context context, Tab tab, Profile profile) {
    mTitle = context.getResources().getString(R.string.ntp_interests);
    mBackgroundColor = NtpColorUtils.getBackgroundColorResource(context.getResources(), false);
    mThemeColor =
        ApiCompatibilityUtils.getColor(context.getResources(), R.color.default_primary_color);
    mPageView = (InterestsView) View.inflate(context, R.layout.interests_page, null);

    new InterestsService(profile)
        .getInterests(
            new GetInterestsCallback() {
              @Override
              public void onInterestsAvailable(Interest[] interests) {
                boolean gotInterests = interests != null;
                RecordHistogram.recordBooleanHistogram(
                    "NewTabPage.Interests.InterestsFetchSuccess", gotInterests);
                if (!gotInterests) {
                  showToastOnFailure();
                  return;
                }
                List<Interest> interestList = Arrays.asList(interests);
                // We use sparse histograms here like in NewTabPage.Snippets.NumArticles,
                // NewTabPage.NumberOfTiles etc as this will measure a small number (< 30)
                // which is expected to be constant for a user and prefer exact counts
                // without defining artificial bucket boundaries.
                RecordHistogram.recordSparseSlowlyHistogram(
                    "NewTabPage.Interests.NumInterests", interestList.size());
                if (interestList.size() == 0) {
                  showToastOnFailure();
                  return;
                }
                mPageView.setInterests(interestList);
              }

              private void showToastOnFailure() {
                Toast.makeText(context, R.string.ntp_no_interests_toast, Toast.LENGTH_SHORT).show();
              }
            });
  }
Ejemplo n.º 16
0
  @Override
  public void onFinishInflate() {
    super.onFinishInflate();
    mLocationBar = (LocationBar) findViewById(R.id.location_bar);

    mHomeButton = (TintedImageButton) findViewById(R.id.home_button);
    mBackButton = (TintedImageButton) findViewById(R.id.back_button);
    mForwardButton = (TintedImageButton) findViewById(R.id.forward_button);
    mReloadButton = (TintedImageButton) findViewById(R.id.refresh_button);
    mShowTabStack =
        DeviceClassManager.isAccessibilityModeEnabled(getContext())
            || CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_TABLET_TAB_STACK);

    mTabSwitcherButtonDrawable =
        TabSwitcherDrawable.createTabSwitcherDrawable(getResources(), false);
    mTabSwitcherButtonDrawableLight =
        TabSwitcherDrawable.createTabSwitcherDrawable(getResources(), true);

    mAccessibilitySwitcherButton = (ImageButton) findViewById(R.id.tab_switcher_button);
    mAccessibilitySwitcherButton.setImageDrawable(mTabSwitcherButtonDrawable);
    updateSwitcherButtonVisibility(mShowTabStack);

    mBookmarkButton = (TintedImageButton) findViewById(R.id.bookmark_button);

    mMenuButton = (TintedImageButton) findViewById(R.id.menu_button);
    mMenuButtonWrapper.setVisibility(shouldShowMenuButton() ? View.VISIBLE : View.GONE);

    if (mAccessibilitySwitcherButton.getVisibility() == View.GONE
        && mMenuButtonWrapper.getVisibility() == View.GONE) {
      ApiCompatibilityUtils.setPaddingRelative(
          (View) mMenuButtonWrapper.getParent(),
          0,
          0,
          getResources().getDimensionPixelSize(R.dimen.tablet_toolbar_end_padding),
          0);
    }
  }
  /**
   * Test a basic printing flow by emulating the corresponding system calls to the printing
   * controller: onStart, onLayout, onWrite, onFinish. Each one is called once, and in this order,
   * in the UI thread.
   */
  @TargetApi(Build.VERSION_CODES.KITKAT)
  @LargeTest
  @Feature({"Printing"})
  public void testNormalPrintingFlow() throws Throwable {
    if (!ApiCompatibilityUtils.isPrintingSupported()) return;

    final ChromeShellTab currentTab = launchChromeShellWithUrl(URL).getActiveTab();
    assertTrue(waitForActiveShellToBeDoneLoading());

    final PrintingControllerImpl printingController = createControllerOnUiThread();

    startControllerOnUiThread(printingController, currentTab);
    // {@link PrintDocumentAdapter#onStart} is always called first.
    callStartOnUiThread(printingController);

    // Create a temporary file to save the PDF.
    final File cacheDir = getInstrumentation().getTargetContext().getCacheDir();
    final File tempFile = File.createTempFile(TEMP_FILE_NAME, TEMP_FILE_EXTENSION, cacheDir);
    final ParcelFileDescriptor fileDescriptor =
        ParcelFileDescriptor.open(
            tempFile, (ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE));

    PrintAttributes attributes =
        new PrintAttributes.Builder()
            .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
            .setResolution(new PrintAttributes.Resolution("foo", "bar", 300, 300))
            .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
            .build();

    // Use this to wait for PDF generation to complete, as it will happen asynchronously.
    final FutureTask<Boolean> result =
        new FutureTask<Boolean>(
            new Callable<Boolean>() {
              @Override
              public Boolean call() {
                return true;
              }
            });

    callLayoutOnUiThread(
        printingController,
        null,
        attributes,
        new LayoutResultCallbackWrapperMock() {
          // Called on UI thread
          @Override
          public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
            callWriteOnUiThread(printingController, fileDescriptor, result);
          }
        });

    FileInputStream in = null;
    try {
      // This blocks until the PDF is generated.
      result.get(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
      assertTrue(tempFile.length() > 0);
      in = new FileInputStream(tempFile);
      byte[] b = new byte[PDF_PREAMBLE.length()];
      in.read(b);
      String preamble = new String(b);
      assertEquals(PDF_PREAMBLE, preamble);
    } finally {
      callFinishOnUiThread(printingController);
      if (in != null) in.close();
      // Close the descriptor, if not closed already.
      fileDescriptor.close();
      TestFileUtil.deleteFile(tempFile.getAbsolutePath());
    }
  }
Ejemplo n.º 18
0
  /**
   * Creates and shows the app menu anchored to the specified view.
   *
   * @param context The context of the AppMenu (ensure the proper theme is set on this context).
   * @param anchorView The anchor {@link View} of the {@link ListPopupWindow}.
   * @param isByPermanentButton Whether or not permanent hardware button triggered it. (oppose to
   *     software button or keyboard).
   * @param screenRotation Current device screen rotation.
   * @param visibleDisplayFrame The display area rect in which AppMenu is supposed to fit in.
   * @param screenHeight Current device screen height.
   * @param footerResourceId The resource id for a view to add to the end of the menu list. Can be 0
   *     if no such view is required.
   */
  void show(
      Context context,
      View anchorView,
      boolean isByPermanentButton,
      int screenRotation,
      Rect visibleDisplayFrame,
      int screenHeight,
      int footerResourceId) {
    mPopup = new ListPopupWindow(context, null, android.R.attr.popupMenuStyle);
    mPopup.setModal(true);
    mPopup.setAnchorView(anchorView);
    mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);

    int footerHeight = 0;
    if (footerResourceId != 0) {
      mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
      View promptView = LayoutInflater.from(context).inflate(footerResourceId, null);
      mPopup.setPromptView(promptView);
      int measureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
      promptView.measure(measureSpec, measureSpec);
      footerHeight = promptView.getMeasuredHeight();
    }
    mPopup.setOnDismissListener(
        new OnDismissListener() {
          @Override
          public void onDismiss() {
            if (mPopup.getAnchorView() instanceof ImageButton) {
              ((ImageButton) mPopup.getAnchorView()).setSelected(false);
            }

            if (mMenuItemEnterAnimator != null) mMenuItemEnterAnimator.cancel();

            mHandler.appMenuDismissed();
            mHandler.onMenuVisibilityChanged(false);
          }
        });

    // Some OEMs don't actually let us change the background... but they still return the
    // padding of the new background, which breaks the menu height.  If we still have a
    // drawable here even though our style says @null we should use this padding instead...
    Drawable originalBgDrawable = mPopup.getBackground();

    // Need to explicitly set the background here.  Relying on it being set in the style caused
    // an incorrectly drawn background.
    if (isByPermanentButton) {
      mPopup.setBackgroundDrawable(
          ApiCompatibilityUtils.getDrawable(context.getResources(), R.drawable.menu_bg));
    } else {
      mPopup.setBackgroundDrawable(
          ApiCompatibilityUtils.getDrawable(context.getResources(), R.drawable.edge_menu_bg));
      mPopup.setAnimationStyle(R.style.OverflowMenuAnim);
    }

    // Turn off window animations for low end devices, and on Android M, which has built-in menu
    // animations.
    if (SysUtils.isLowEndDevice() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      mPopup.setAnimationStyle(0);
    }

    Rect bgPadding = new Rect();
    mPopup.getBackground().getPadding(bgPadding);

    int popupWidth =
        context.getResources().getDimensionPixelSize(R.dimen.menu_width)
            + bgPadding.left
            + bgPadding.right;

    mPopup.setWidth(popupWidth);

    mCurrentScreenRotation = screenRotation;
    mIsByPermanentButton = isByPermanentButton;

    // Extract visible items from the Menu.
    int numItems = mMenu.size();
    List<MenuItem> menuItems = new ArrayList<MenuItem>();
    for (int i = 0; i < numItems; ++i) {
      MenuItem item = mMenu.getItem(i);
      if (item.isVisible()) {
        menuItems.add(item);
      }
    }

    Rect sizingPadding = new Rect(bgPadding);
    if (isByPermanentButton && originalBgDrawable != null) {
      Rect originalPadding = new Rect();
      originalBgDrawable.getPadding(originalPadding);
      sizingPadding.top = originalPadding.top;
      sizingPadding.bottom = originalPadding.bottom;
    }

    // A List adapter for visible items in the Menu. The first row is added as a header to the
    // list view.
    mAdapter = new AppMenuAdapter(this, menuItems, LayoutInflater.from(context));
    mPopup.setAdapter(mAdapter);

    setMenuHeight(menuItems.size(), visibleDisplayFrame, screenHeight, sizingPadding, footerHeight);
    setPopupOffset(mPopup, mCurrentScreenRotation, visibleDisplayFrame, sizingPadding);
    mPopup.setOnItemClickListener(this);
    mPopup.show();
    mPopup.getListView().setItemsCanFocus(true);
    mPopup.getListView().setOnKeyListener(this);

    mHandler.onMenuVisibilityChanged(true);

    if (mVerticalFadeDistance > 0) {
      mPopup.getListView().setVerticalFadingEdgeEnabled(true);
      mPopup.getListView().setFadingEdgeLength(mVerticalFadeDistance);
    }

    // Don't animate the menu items for low end devices.
    if (!SysUtils.isLowEndDevice() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      mPopup
          .getListView()
          .addOnLayoutChangeListener(
              new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(
                    View v,
                    int left,
                    int top,
                    int right,
                    int bottom,
                    int oldLeft,
                    int oldTop,
                    int oldRight,
                    int oldBottom) {
                  mPopup.getListView().removeOnLayoutChangeListener(this);
                  runMenuItemEnterAnimations();
                }
              });
    }
  }
Ejemplo n.º 19
0
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (convertView == null) {
      view = mLayoutInflater.inflate(R.layout.search_engine, null);
    }

    view.setOnClickListener(this);
    view.setTag(position);

    // TODO(finnur): There's a tinting bug in the AppCompat lib (see http://crbug.com/474695),
    // which causes the first radiobox to always appear selected, even if it is not. It is being
    // addressed, but in the meantime we should use the native RadioButton instead.
    RadioButton radioButton = (RadioButton) view.findViewById(R.id.radiobutton);
    // On Lollipop this removes the redundant animation ring on selection but on older versions
    // it would cause the radio button to disappear.
    // TODO(finnur): Remove the encompassing if statement once we go back to using the AppCompat
    // control.
    final boolean selected = position == mSelectedSearchEnginePosition;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      radioButton.setBackgroundResource(0);
    }
    radioButton.setChecked(selected);

    TextView description = (TextView) view.findViewById(R.id.description);
    TemplateUrl templateUrl = mSearchEngines.get(position);
    Resources resources = mContext.getResources();
    description.setText(templateUrl.getShortName());

    // To improve the explore-by-touch experience, the radio button is hidden from accessibility
    // and instead, "checked" or "not checked" is read along with the search engine's name, e.g.
    // "google.com checked" or "google.com not checked".
    radioButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
    description.setAccessibilityDelegate(
        new AccessibilityDelegate() {
          @Override
          public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
            super.onInitializeAccessibilityEvent(host, event);
            event.setChecked(selected);
          }

          @Override
          public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(host, info);
            info.setCheckable(true);
            info.setChecked(selected);
          }
        });

    TextView link = (TextView) view.findViewById(R.id.link);
    link.setVisibility(selected ? View.VISIBLE : View.GONE);
    if (selected) {
      ForegroundColorSpan linkSpan =
          new ForegroundColorSpan(
              ApiCompatibilityUtils.getColor(resources, R.color.pref_accent_color));
      if (LocationSettings.getInstance().isSystemLocationSettingEnabled()) {
        String message =
            mContext.getString(
                locationEnabled(position, true)
                    ? R.string.search_engine_location_allowed
                    : R.string.search_engine_location_blocked);
        SpannableString messageWithLink = new SpannableString(message);
        messageWithLink.setSpan(linkSpan, 0, messageWithLink.length(), 0);
        link.setText(messageWithLink);
      } else {
        link.setText(
            SpanApplier.applySpans(
                mContext.getString(R.string.android_location_off),
                new SpanInfo("<link>", "</link>", linkSpan)));
      }

      link.setOnClickListener(this);
    }

    return view;
  }
Ejemplo n.º 20
0
  private void updateLayoutParams() {
    int startMargin = 0;
    int locationBarLayoutChildIndex = -1;
    for (int i = 0; i < getChildCount(); i++) {
      View childView = getChildAt(i);
      if (childView.getVisibility() != GONE) {
        LayoutParams childLayoutParams = (LayoutParams) childView.getLayoutParams();
        if (ApiCompatibilityUtils.getMarginStart(childLayoutParams) != startMargin) {
          ApiCompatibilityUtils.setMarginStart(childLayoutParams, startMargin);
          childView.setLayoutParams(childLayoutParams);
        }
        if (childView == mLocationBarFrameLayout) {
          locationBarLayoutChildIndex = i;
          break;
        }
        int widthMeasureSpec;
        int heightMeasureSpec;
        if (childLayoutParams.width == LayoutParams.WRAP_CONTENT) {
          widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST);
        } else if (childLayoutParams.width == LayoutParams.MATCH_PARENT) {
          widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
        } else {
          widthMeasureSpec =
              MeasureSpec.makeMeasureSpec(childLayoutParams.width, MeasureSpec.EXACTLY);
        }
        if (childLayoutParams.height == LayoutParams.WRAP_CONTENT) {
          heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST);
        } else if (childLayoutParams.height == LayoutParams.MATCH_PARENT) {
          heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY);
        } else {
          heightMeasureSpec =
              MeasureSpec.makeMeasureSpec(childLayoutParams.height, MeasureSpec.EXACTLY);
        }
        childView.measure(widthMeasureSpec, heightMeasureSpec);
        startMargin += childView.getMeasuredWidth();
      }
    }

    assert locationBarLayoutChildIndex != -1;
    int locationBarLayoutEndMargin = 0;
    for (int i = locationBarLayoutChildIndex + 1; i < getChildCount(); i++) {
      View childView = getChildAt(i);
      if (childView.getVisibility() != GONE) {
        locationBarLayoutEndMargin += childView.getMeasuredWidth();
      }
    }
    LayoutParams urlLayoutParams = (LayoutParams) mLocationBarFrameLayout.getLayoutParams();

    if (ApiCompatibilityUtils.getMarginEnd(urlLayoutParams) != locationBarLayoutEndMargin) {
      ApiCompatibilityUtils.setMarginEnd(urlLayoutParams, locationBarLayoutEndMargin);
      mLocationBarFrameLayout.setLayoutParams(urlLayoutParams);
    }

    // Update left margin of mTitleUrlContainer here to make sure the security icon is always
    // placed left of the urlbar.
    LayoutParams lp = (LayoutParams) mTitleUrlContainer.getLayoutParams();
    if (mSecurityButton.getVisibility() == View.GONE) {
      lp.leftMargin = 0;
    } else {
      lp.leftMargin = mSecurityButton.getMeasuredWidth();
    }
    mTitleUrlContainer.setLayoutParams(lp);
  }
Ejemplo n.º 21
0
 /** Updates the title of chrome shown in recent tasks. It only takes effect in document mode. */
 public static void setTaskDescriptionInDocumentMode(Activity activity, String description) {
   if (FeatureUtilities.isDocumentMode(activity)) {
     // Setting icon to be null and color to be 0 will means "take no effect".
     ApiCompatibilityUtils.setTaskDescription(activity, description, null, 0);
   }
 }
Ejemplo n.º 22
0
  /**
   * Pushes all relevant {@link LayoutTab}s from a {@link Layout} to the CC Layer tree. This will
   * let them be rendered on the screen. This should only be called when the Compositor has disabled
   * ScheduleComposite calls as this will change the tree and could subsequently cause unnecessary
   * follow up renders.
   *
   * @param context The {@link Context} to use to query device information.
   * @param layout The {@link Layout} to push to the screen.
   */
  public void pushLayers(
      Context context,
      Rect viewport,
      Rect contentViewport,
      Layout layout,
      LayerTitleCache layerTitleCache,
      TabContentManager tabContentManager,
      ResourceManager resourceManager) {
    if (mNativePtr == 0) return;

    Resources res = context.getResources();
    final float dpToPx = res.getDisplayMetrics().density;

    LayoutTab[] tabs = layout.getLayoutTabsToRender();
    int tabsCount = tabs != null ? tabs.length : 0;

    nativeBeginBuildingFrame(mNativePtr);
    for (int i = 0; i < tabsCount; i++) {
      LayoutTab t = tabs[i];
      assert t.isVisible() : "LayoutTab in that list should be visible";
      final float decoration = t.getDecorationAlpha();

      int borderResource =
          t.isIncognito()
              ? R.drawable.tabswitcher_border_frame_incognito
              : R.drawable.tabswitcher_border_frame;
      int closeBtnResource =
          t.isIncognito() ? R.drawable.btn_tab_close_white_normal : R.drawable.btn_tab_close_normal;
      int borderColorResource = t.isIncognito() ? R.color.tab_back_incognito : R.color.tab_back;
      // TODO(dtrainor, clholgat): remove "* dpToPx" once the native part fully supports dp.
      nativePutLayer(
          mNativePtr,
          t.getId(),
          R.id.control_container,
          closeBtnResource,
          R.drawable.tabswitcher_border_frame_shadow,
          R.drawable.tabswitcher_border_frame_decoration,
          R.drawable.logo_card_back,
          borderResource,
          t.canUseLiveTexture(),
          (t.getFallbackThumbnailId() == ChromeTab.NTP_TAB_ID),
          t.getBackgroundColor(),
          ApiCompatibilityUtils.getColor(res, R.color.tab_switcher_background),
          ApiCompatibilityUtils.getColor(res, borderColorResource),
          t.isIncognito(),
          layout.getOrientation() == Orientation.PORTRAIT,
          t.getRenderX() * dpToPx,
          t.getRenderY() * dpToPx,
          t.getScaledContentWidth() * dpToPx,
          t.getScaledContentHeight() * dpToPx,
          t.getOriginalContentWidth() * dpToPx,
          t.getOriginalContentHeight() * dpToPx,
          contentViewport.height(),
          viewport.left,
          viewport.top,
          viewport.width(),
          viewport.height(),
          t.getClippedX() * dpToPx,
          t.getClippedY() * dpToPx,
          Math.min(t.getClippedWidth(), t.getScaledContentWidth()) * dpToPx,
          Math.min(t.getClippedHeight(), t.getScaledContentHeight()) * dpToPx,
          t.getTiltXPivotOffset() * dpToPx,
          t.getTiltYPivotOffset() * dpToPx,
          t.getTiltX(),
          t.getTiltY(),
          t.getAlpha(),
          t.getBorderAlpha() * decoration,
          decoration,
          t.getShadowOpacity() * decoration,
          t.getBorderCloseButtonAlpha() * decoration,
          LayoutTab.CLOSE_BUTTON_WIDTH_DP * dpToPx,
          t.getStaticToViewBlend(),
          t.getBorderScale(),
          t.getSaturation(),
          t.getBrightness(),
          t.showToolbar(),
          t.anonymizeToolbar(),
          t.getTextBoxBackgroundColor(),
          t.getToolbarAlpha(),
          t.getToolbarYOffset() * dpToPx,
          t.getSideBorderScale(),
          true,
          t.insetBorderVertical(),
          layerTitleCache,
          tabContentManager,
          resourceManager);
    }
    nativeFinishBuildingFrame(mNativePtr);
  }
Ejemplo n.º 23
0
 @VisibleForTesting
 protected boolean shouldSkipFirstUseHints() {
   return ApiCompatibilityUtils.shouldSkipFirstUseHints(mActivity.getContentResolver());
 }