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

Commit c9536b8e authored by Fan Zhang's avatar Fan Zhang
Browse files

UI Refresh: a new app info header for app/notification.

- moved force stop and uninstall button to bottom of page (as footer)
- Forked appheader layout file, and created AppHeaderController to
  contain all binding logic for header.

Bug: 32442716
Test: RunSettingsRoboTests
Change-Id: Id4eb365ca25e035c043c068867f5cbc3a202b201
parent 9895344b
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright (C) 2016 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.
  -->

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="bottom"
    android:paddingTop="4dp"
    android:paddingStart="8dp"
    android:paddingEnd="8dp"
    android:orientation="horizontal">

    <Button
        android:id="@+id/left_button"
        style="@style/AppActionPrimaryButton"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:paddingEnd="8dp"/>

    <Button
        android:id="@+id/right_button"
        style="@style/AppActionPrimaryButton"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:paddingStart="8dp"/>

</LinearLayout>
 No newline at end of file
+91 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright (C) 2016 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.
  -->

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/app_snippet"
    style="@style/AppHeader"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal|top"
    android:orientation="vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">

    <!-- App snippet with buttons -->
    <ImageView
        android:id="@android:id/icon"
        android:layout_marginTop="16dp"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:scaleType="fitXY"
        android:layout_gravity="center_horizontal"
        android:antialias="true"/>

    <TextView
        android:id="@android:id/title"
        style="@style/TextAppearance.AppHeaderTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:gravity="center_horizontal"
        android:paddingTop="8dp"/>

    <TextView
        android:id="@android:id/summary"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:textAppearance="@android:style/TextAppearance.Material.Body1"
        android:textColor="?android:attr/textColorSecondary"/>

    <LinearLayout
        android:id="@+id/app_detail_links"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="bottom"
        android:paddingStart="8dp"
        android:paddingEnd="8dp"
        android:orientation="horizontal">

        <ImageButton
            android:id="@+id/left_button"
            style="@style/AppHeaderLinkButton"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:paddingEnd="8dp"
            android:tint="?android:attr/colorAccent"/>

        <ImageButton
            android:id="@+id/right_button"
            style="@style/AppHeaderLinkButton"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:paddingStart="8dp"
            android:src="@drawable/ic_settings_24dp"
            android:tint="?android:attr/colorAccent"/>

    </LinearLayout>

</LinearLayout>
 No newline at end of file
+18 −0
Original line number Diff line number Diff line
@@ -452,4 +452,22 @@
        <item name="android:progressDrawable">@drawable/ring_progress</item>
    </style>

    <style name="AppHeader">
        <item name="android:background">@color/card_background_grey</item>
        <item name="android:gravity">center_horizontal</item>
        <item name="android:paddingStart">16dp</item>
        <item name="android:paddingEnd">16dp</item>
        <item name="android:paddingBottom">16dp</item>
    </style>

    <style name="TextAppearance.AppHeaderTitle"
           parent="@android:style/TextAppearance.Material.Subhead">
        <item name="android:textColor">?android:attr/textColorPrimary</item>
        <item name="android:textSize">24sp</item>
    </style>

    <style name="AppHeaderLinkButton" parent="android:Widget.Material.Button.Borderless"/>

    <style name="AppActionPrimaryButton" parent="android:Widget.Material.Button.Colored"/>

</resources>
+61 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright (C) 2016 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.
  -->

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <com.android.settings.applications.LayoutPreference
        android:key="header_view"
        android:layout="@layout/app_details"
        android:selectable="false"/>

    <Preference
        android:key="storage_settings"
        android:title="@string/storage_settings"
        android:selectable="true"/>

    <Preference
        android:key="data_settings"
        android:title="@string/data_usage_summary_title"
        android:selectable="true"/>

    <Preference
        android:key="permission_settings"
        android:title="@string/permissions_label"
        android:selectable="true"/>

    <Preference
        android:key="notification_settings"
        android:title="@string/notifications_label"
        android:selectable="true"/>

    <Preference
        android:key="preferred_settings"
        android:title="@string/launch_by_default"
        android:selectable="true"/>

    <Preference
        android:key="battery"
        android:title="@string/power_usage_summary_title"
        android:selectable="true"/>

    <Preference
        android:key="memory"
        android:title="@string/memory_settings_title"
        android:enabled="false"
        android:selectable="true"/>

</PreferenceScreen>
 No newline at end of file
+163 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.settings.applications;

import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.support.annotation.IntDef;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settingslib.applications.ApplicationsState;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class AppHeaderController {

    @IntDef({ActionType.ACTION_APP_INFO,
            ActionType.ACTION_APP_PREFERENCE,
            ActionType.ACTION_STORE_DEEP_LINK,
            ActionType.ACTION_NOTIF_PREFERENCE})
    @Retention(RetentionPolicy.SOURCE)
    @interface ActionType {
        int ACTION_APP_INFO = 0;
        int ACTION_STORE_DEEP_LINK = 1;
        int ACTION_APP_PREFERENCE = 2;
        int ACTION_NOTIF_PREFERENCE = 3;
    }

    private static final String TAG = "AppDetailFeature";

    private final Context mContext;

    public AppHeaderController(Context context) {
        mContext = context;
    }

    public void bindAppHeader(View appSnippet, PackageInfo packageInfo,
            ApplicationsState.AppEntry appEntry) {
        final String versionName = packageInfo == null ? null : packageInfo.versionName;
        final Resources res = appSnippet.getResources();

        // Set Icon
        final ImageView iconView = (ImageView) appSnippet.findViewById(android.R.id.icon);
        if (appEntry.icon != null) {
            iconView.setImageDrawable(appEntry.icon.getConstantState().newDrawable(res));
        }

        // Set application name.
        final TextView labelView = (TextView) appSnippet.findViewById(android.R.id.title);
        labelView.setText(appEntry.label);

        // Version number of application
        final TextView appVersion = (TextView) appSnippet.findViewById(android.R.id.summary);

        if (!TextUtils.isEmpty(versionName)) {
            appVersion.setSelected(true);
            appVersion.setVisibility(View.VISIBLE);
            appVersion.setText(res.getString(R.string.version_text, String.valueOf(versionName)));
        } else {
            appVersion.setVisibility(View.INVISIBLE);
        }
    }

    public void bindAppHeaderButtons(Fragment fragment, View appLinkButtons, String packageName,
            @ActionType int leftAction, @ActionType int rightAction) {
        ImageButton leftButton = (ImageButton) appLinkButtons.findViewById(R.id.left_button);
        ImageButton rightButton = (ImageButton) appLinkButtons.findViewById(R.id.right_button);

        bindAppDetailButton(fragment, packageName, leftButton, leftAction);
        bindAppDetailButton(fragment, packageName, rightButton, rightAction);
    }

    private void bindAppDetailButton(Fragment fragment, String packageName,
            ImageButton button, @ActionType int action) {
        if (button == null) {
            return;
        }
        switch (action) {
            case ActionType.ACTION_APP_INFO: {
                if (packageName == null || packageName.equals(Utils.OS_PKG)) {
                    button.setVisibility(View.GONE);
                } else {
                    // TODO
                    button.setImageResource(com.android.settings.R.drawable.ic_info);
                    button.setVisibility(View.VISIBLE);
                }
                return;
            }
            case ActionType.ACTION_STORE_DEEP_LINK: {
                final Intent intent = new Intent(Intent.ACTION_SHOW_APP_INFO)
                        .setPackage(getInstallerPackageName(mContext, packageName));
                final Intent result = resolveIntent(intent);
                if (result == null) {
                    button.setVisibility(View.GONE);
                } else {
                    result.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
                    button.setImageResource(R.drawable.ic_sim_sd);
                    button.setOnClickListener(v -> fragment.startActivity(intent));
                    button.setVisibility(View.VISIBLE);
                }
                return;
            }
            case ActionType.ACTION_NOTIF_PREFERENCE: {
                // TODO
                return;
            }
            case ActionType.ACTION_APP_PREFERENCE: {
                final Intent intent = resolveIntent(
                        new Intent(Intent.ACTION_APPLICATION_PREFERENCES).setPackage(packageName));
                if (intent == null) {
                    button.setVisibility(View.GONE);
                    return;
                }
                button.setOnClickListener(v -> fragment.startActivity(intent));
                button.setVisibility(View.VISIBLE);
                return;
            }
        }
    }

    private String getInstallerPackageName(Context context, String packageName) {
        try {
            return context.getPackageManager().getInstallerPackageName(packageName);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Exception while retrieving the package installer of " + packageName, e);
            return null;
        }
    }

    private Intent resolveIntent(Intent i) {
        ResolveInfo result = mContext.getPackageManager().resolveActivity(i, 0);
        if (result != null) {
            return new Intent(i.getAction())
                    .setClassName(result.activityInfo.packageName, result.activityInfo.name);
        }
        return null;
    }
}
Loading