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

Commit 8b678cf9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I67b5e0f2,I117cc713 into main

* changes:
  [PM] Support material AlertDialog (2/N)
  [PM] Support material AlertDialog (1/N)
parents bb5384bb e3468314
Loading
Loading
Loading
Loading
+35 −11
Original line number Diff line number Diff line
@@ -16,18 +16,13 @@
  -->
<resources>

    <style name="Widget.PackageInstaller.Button" parent="android:Widget.DeviceDefault.Button">
        <item name="android:textColor">?android:attr/colorAccent</item>
        <item name="android:background">@null</item>
        <item name="android:minHeight">@dimen/button_min_height</item>
        <item name="android:layout_marginStart">8dp</item>
    </style>

    <!-- TODO (b/274120822): Remove these styles when we replace all dialogs to MaterialAlertDialog -->
    <style name="Widget.PackageInstaller.Button.Colored" parent="android:Widget.DeviceDefault.Button.Colored">
        <item name="android:background">@drawable/background_colored_button</item>
        <item name="android:minHeight">@dimen/button_min_height</item>
        <item name="android:paddingHorizontal">24dp</item>
        <item name="android:layout_marginStart">8dp</item>
        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
    </style>

    <style name="Widget.PackageInstaller.Button.Outlined" parent="android:Widget.DeviceDefault.Button.Colored">
@@ -35,12 +30,14 @@
        <item name="android:textColor">?android:attr/colorAccent</item>
        <item name="android:minHeight">@dimen/button_min_height</item>
        <item name="android:layout_marginStart">8dp</item>
        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
    </style>

    <style name="Widget.PackageInstaller.ButtonBar" parent="">
        <item name="android:paddingBottom">20dp</item>
        <item name="android:paddingTop">4dp</item>
        <item name="android:paddingHorizontal">12dp</item>
        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
    </style>

    <style name="Widget.PackageInstaller.WindowTitle" parent="">
@@ -49,21 +46,48 @@
        <item name="android:autoSizeTextType">uniform</item>
    </style>

    <style name="Widget.PackageInstaller.Material.WindowTitle" parent="@style/MaterialAlertDialog.Material3.Title.Text">
        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Headline</item>
        <item name="android:layout_marginTop">4dp</item>
        <item name="android:autoSizeTextType">uniform</item>
    </style>

    <style name="Widget.PackageInstaller.Material.Button" parent="@style/Widget.Material3.Button.TextButton">
        <item name="android:textColor">?android:attr/colorAccent</item>
        <item name="android:minHeight">@dimen/button_min_height</item>
        <item name="android:layout_marginStart">8dp</item>
        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
    </style>

    <style name="Widget.PackageInstaller.Material.Button.Colored" parent="@style/Widget.Material3.Button">
        <item name="android:minHeight">@dimen/button_min_height</item>
        <item name="android:paddingHorizontal">24dp</item>
        <item name="android:layout_marginStart">8dp</item>
        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
    </style>

    <style name="Widget.PackageInstaller.Material.Button.Outlined" parent="@style/Widget.Material3.Button.OutlinedButton">
        <item name="android:textColor">?android:attr/colorAccent</item>
        <item name="android:minHeight">@dimen/button_min_height</item>
        <item name="android:layout_marginStart">8dp</item>
        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
    </style>

    <style name="Widget.PackageInstaller.TextView.AppLabel" parent="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle">
        <item name="android:textFontWeight">600</item>
        <item name="android:color">?android:attr/textColorPrimary</item>
    </style>

    <style name="Widget.PackageInstaller.TextView.CustomMessage" parent="@android:style/TextAppearance.DeviceDefault.Small">
    <style name="Widget.PackageInstaller.TextView.CustomMessage" parent="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle">
        <item name="android:textColor">?android:attr/textColorSecondary</item>
    </style>

    <style name="Widget.PackageInstaller.TextView.KeepData.Heading" parent="@android:style/TextAppearance.DeviceDefault.Small">
    <style name="Widget.PackageInstaller.TextView.KeepData.Heading" parent="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle">
        <item name="android:textColor">?android:attr/textColorSecondary</item>
        <item name="android:textFontWeight">600</item>
    </style>

    <style name="Widget.PackageInstaller.TextView.KeepData.SubHeading" parent="@android:style/TextAppearance.DeviceDefault.Small">
    <style name="Widget.PackageInstaller.TextView.KeepData.SubHeading" parent="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle">
        <item name="android:textColor">?android:attr/textColorSecondary</item>
    </style>
</resources>
+15 −6
Original line number Diff line number Diff line
@@ -24,20 +24,29 @@
        <item name="android:windowAnimationStyle">@null</item>
    </style>

    <style name="Theme.AlertDialogActivity.Material" >
        <item name="android:alertDialogTheme">@style/Theme.MaterialAlertDialog</item>
    <style name="Theme.AlertDialogActivity.Material" parent="Theme.Material3.DynamicColors.DayNight">
        <!-- TODO (b/274120822): Remove this attribute when we replace all dialogs to MaterialAlertDialog -->
        <item name="android:alertDialogTheme">@style/Theme.MaterialAlertDialog.System</item>
        <item name="materialAlertDialogTheme">@style/Theme.MaterialAlertDialog</item>
    </style>

    <style name="Theme.MaterialAlertDialog" parent="@style/Theme.AlertDialogActivity">
    <!-- TODO (b/274120822): Remove this theme when we replace all dialogs to MaterialAlertDialog -->
    <style name="Theme.MaterialAlertDialog.System" parent="@style/Theme.AlertDialogActivity">
        <item name="android:buttonBarPositiveButtonStyle">@style/Widget.PackageInstaller.Button.Colored</item>
        <item name="android:buttonBarNegativeButtonStyle">@style/Widget.PackageInstaller.Button.Outlined</item>
        <item name="android:buttonBarStyle">@style/Widget.PackageInstaller.ButtonBar</item>
        <item name="android:windowTitleStyle">@style/Widget.PackageInstaller.WindowTitle</item>
    </style>

    <style name="Theme.MaterialAlertDialog.Variant">
        <item name="android:buttonBarPositiveButtonStyle">@style/Widget.PackageInstaller.Button</item>
        <item name="android:buttonBarNegativeButtonStyle">@style/Widget.PackageInstaller.Button</item>
    <style name="Theme.MaterialAlertDialog" parent="@style/ThemeOverlay.Material3.MaterialAlertDialog">
        <item name="buttonBarPositiveButtonStyle">@style/Widget.PackageInstaller.Material.Button.Colored</item>
        <item name="buttonBarNegativeButtonStyle">@style/Widget.PackageInstaller.Material.Button.Outlined</item>
        <item name="materialAlertDialogTitleTextStyle">@style/Widget.PackageInstaller.Material.WindowTitle</item>
    </style>

    <style name="Theme.MaterialAlertDialog.Variant" parent="@style/Theme.MaterialAlertDialog.System">
        <item name="buttonBarPositiveButtonStyle">@style/Widget.PackageInstaller.Material.Button</item>
        <item name="buttonBarNegativeButtonStyle">@style/Widget.PackageInstaller.Material.Button</item>
    </style>

    <style name="Theme.UninstallerActivity"
+1 −5
Original line number Diff line number Diff line
@@ -89,11 +89,7 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
        // theme to support the material design.
        if (PackageUtil.isMaterialDesignEnabled(this)) {
            Log.d(LOG_TAG, "Apply material design")
            theme.applyStyle(R.style.Theme_AlertDialogActivity_Material, /* force= */ true)
            // Apply the material theme for the material components
            theme.applyStyle(
                com.google.android.material.R.style.Theme_Material3_DynamicColors_DayNight,
                /* force= */ false)
            theme.applyStyle(R.style.Theme_AlertDialogActivity_Material, /* force= */ false)
        }

        fragmentManager = supportFragmentManager
+124 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.packageinstaller.v2.ui;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
import android.widget.Button;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.packageinstaller.R;
import com.android.packageinstaller.v2.model.PackageUtil;

import com.google.android.material.dialog.MaterialAlertDialogBuilder;

/**
 * The utility of UI components.
 */
public class UiUtil {

    public static final String LOG_TAG = UiUtil.class.getSimpleName();
    /**
     * If material design is enabled, return the material layout resource id. Otherwise, return the
     * default layout resource id.
     */
    public static int getInstallationLayoutResId(@NonNull Context context) {
        if (PackageUtil.isMaterialDesignEnabled(context)) {
            return R.layout.install_fragment_material_layout;
        } else {
            return R.layout.install_fragment_layout;
        }
    }

    /** If material design is enabled, return the material theme resource id of the text button.
     * Otherwise, return {@code 0} to use the default theme.
     */
    public static int getTextButtonThemeResId(@NonNull Context context) {
        return PackageUtil.isMaterialDesignEnabled(context)
                ? R.style.Theme_MaterialAlertDialog_Variant : 0;
    }

    /**
     * Gets the positive button in the {@code dialog}. Returns null if the specified
     * button does not exist or the dialog has not yet been fully created.
     */
    public static Button getAlertDialogPositiveButton(@NonNull Dialog dialog) {
        return getAlertiDialogButton(dialog, DialogInterface.BUTTON_POSITIVE);
    }

    /**
     * Gets one of the buttons used in the {@code dialog}. Returns null if the specified
     * button does not exist or the dialog has not yet been fully created.
     *
     * @param whichButton The identifier of the button that should be returned.
     *            For example, this can be {@link DialogInterface#BUTTON_POSITIVE}.
     * @return The button from the dialog, or null if a button does not exist.
     */
    @Nullable
    private static Button getAlertiDialogButton(@NonNull Dialog dialog, int whichButton) {
        if (dialog instanceof android.app.AlertDialog alertDialog) {
            return alertDialog.getButton(whichButton);
        } else if (dialog instanceof androidx.appcompat.app.AlertDialog alertDialog) {
            return alertDialog.getButton(whichButton);
        } else {
            return null;
        }
    }

    /**
     * If material design is enabled, return the MaterialAlertDialog. Otherwise, return the
     * system AlertDialog.
     */
    public static Dialog getAlertDialog(@NonNull Context context, @NonNull String title,
            @NonNull View contentView, int positiveBtnTextResId, int negativeBtnTextResId,
            @Nullable DialogInterface.OnClickListener positiveBtnListener,
            @Nullable DialogInterface.OnClickListener negativeBtnListener) {
        return getAlertDialog(context, title, contentView, positiveBtnTextResId,
                negativeBtnTextResId, positiveBtnListener, negativeBtnListener,
                /* themeResId= */ 0);
    }

    /**
     * If material design is enabled, return the MaterialAlertDialog. Otherwise, return the
     * system AlertDialog.
     */
    public static Dialog getAlertDialog(@NonNull Context context,
            @NonNull String title, @NonNull View contentView, int positiveBtnTextResId,
            int negativeBtnTextResId, @Nullable DialogInterface.OnClickListener positiveBtnListener,
            @Nullable DialogInterface.OnClickListener negativeBtnListener, int themeResId) {
        if (PackageUtil.isMaterialDesignEnabled(context)) {
            return new MaterialAlertDialogBuilder(context, themeResId)
                    .setTitle(title)
                    .setView(contentView)
                    .setPositiveButton(positiveBtnTextResId, positiveBtnListener)
                    .setNegativeButton(negativeBtnTextResId, negativeBtnListener)
                    .create();
        } else {
            return new AlertDialog.Builder(context, themeResId)
                    .setTitle(title)
                    .setView(contentView)
                    .setPositiveButton(positiveBtnTextResId, positiveBtnListener)
                    .setNegativeButton(negativeBtnTextResId, negativeBtnListener)
                    .create();
        }
    }
}
+25 −24
Original line number Diff line number Diff line
@@ -16,13 +16,13 @@

package com.android.packageinstaller.v2.ui.fragments;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
@@ -31,8 +31,8 @@ import androidx.fragment.app.DialogFragment;
import com.android.packageinstaller.R;
import com.android.packageinstaller.v2.model.InstallStage;
import com.android.packageinstaller.v2.model.InstallUserActionRequired;
import com.android.packageinstaller.v2.model.PackageUtil;
import com.android.packageinstaller.v2.ui.InstallActionListener;
import com.android.packageinstaller.v2.ui.UiUtil;

/**
 * Dialog to show when the source of apk can not be identified.
@@ -43,7 +43,7 @@ public class AnonymousSourceFragment extends DialogFragment {
    @NonNull
    private InstallActionListener mInstallActionListener;
    @NonNull
    private AlertDialog mDialog;
    private Dialog mDialog;

    @Override
    public void onAttach(@NonNull Context context) {
@@ -56,28 +56,20 @@ public class AnonymousSourceFragment extends DialogFragment {
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Log.i(LOG_TAG, "Creating " + LOG_TAG);

        View dialogView = getLayoutInflater().inflate(R.layout.install_fragment_layout, null);
        View dialogView = getLayoutInflater().inflate(
                UiUtil.getInstallationLayoutResId(requireContext()), null);
        TextView customMessage = dialogView.requireViewById(R.id.custom_message);
        customMessage.setText(R.string.message_anonymous_source_warning);
        customMessage.setVisibility(View.VISIBLE);

        int themeResId = 0;
        // The base theme inherits a deviceDefault theme. Applying a material style on the base
        // theme to support the material design.
        if (PackageUtil.isMaterialDesignEnabled(requireContext())) {
            Log.d(LOG_TAG, "Apply material design");
            themeResId = R.style.Theme_MaterialAlertDialog_Variant;
        }

        mDialog = new AlertDialog.Builder(requireContext(), themeResId)
                .setTitle(R.string.title_anonymous_source_warning)
                .setView(dialogView)
                .setPositiveButton(R.string.button_continue,
        mDialog = UiUtil.getAlertDialog(requireContext(),
                getString(R.string.title_anonymous_source_warning), dialogView,
                R.string.button_continue, R.string.button_cancel,
                ((dialog, which) -> mInstallActionListener.onPositiveResponse(
                                InstallUserActionRequired.USER_ACTION_REASON_ANONYMOUS_SOURCE)))
                .setNegativeButton(R.string.button_cancel,
                        InstallUserActionRequired.USER_ACTION_REASON_ANONYMOUS_SOURCE)),
                ((dialog, which) -> mInstallActionListener.onNegativeResponse(
                                InstallStage.STAGE_USER_ACTION_REQUIRED))).create();
                        InstallStage.STAGE_USER_ACTION_REQUIRED)),
                UiUtil.getTextButtonThemeResId(requireContext()));
        return mDialog;
    }

@@ -90,7 +82,10 @@ public class AnonymousSourceFragment extends DialogFragment {
    @Override
    public void onStart() {
        super.onStart();
        mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
        Button button = UiUtil.getAlertDialogPositiveButton(mDialog);
        if (button != null) {
            button.setFilterTouchesWhenObscured(true);
        }
    }

    @Override
@@ -98,12 +93,18 @@ public class AnonymousSourceFragment extends DialogFragment {
        super.onPause();
        // This prevents tapjacking since an overlay activity started in front of Pia will
        // cause Pia to be paused.
        mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
        Button button = UiUtil.getAlertDialogPositiveButton(mDialog);
        if (button != null) {
            button.setEnabled(false);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
        Button button = UiUtil.getAlertDialogPositiveButton(mDialog);
        if (button != null) {
            button.setEnabled(true);
        }
    }
}
Loading