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

Commit 6d8b89a7 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add preference controller for app header view."

parents 35d37784 e712aed3
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.appinfo;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.support.v7.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.core.lifecycle.Lifecycle;

public class AppHeaderViewPreferenceController extends BasePreferenceController
        implements AppInfoDashboardFragment.Callback {

    private static final String KEY_HEADER = "header_view";

    private LayoutPreference mHeader;
    private final AppInfoDashboardFragment mParent;
    private final String mPackageName;
    private final Lifecycle mLifecycle;

    public AppHeaderViewPreferenceController(Context context, AppInfoDashboardFragment parent,
            String packageName, Lifecycle lifecycle) {
        super(context, KEY_HEADER);
        mParent = parent;
        mPackageName = packageName;
        mLifecycle = lifecycle;
    }

    @Override
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mHeader = (LayoutPreference) screen.findPreference(KEY_HEADER);
        final Activity activity = mParent.getActivity();
        EntityHeaderController
                .newInstance(activity, mParent, mHeader.findViewById(R.id.entity_header))
                .setRecyclerView(mParent.getListView(), mLifecycle)
                .setPackageName(mPackageName)
                .setHasAppInfoLink(false)
                .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
                        EntityHeaderController.ActionType.ACTION_NONE)
                .styleActionBar(activity)
                .bindHeaderButtons();
    }

    @Override
    public void refreshUi() {
        setAppLabelAndIcon(mParent.getPackageInfo(), mParent.getAppEntry());
    }

    // Utility method to set application label and icon.
    private void setAppLabelAndIcon(PackageInfo pkgInfo, AppEntry appEntry) {
        final Activity activity = mParent.getActivity();
        final boolean isInstantApp = AppUtils.isInstant(pkgInfo.applicationInfo);
        final CharSequence summary = isInstantApp
                ? null : mContext.getString(Utils.getInstallationStatus(appEntry.info));
        EntityHeaderController
                .newInstance(activity, mParent, mHeader.findViewById(R.id.entity_header))
                .setLabel(appEntry)
                .setIcon(appEntry)
                .setSummary(summary)
                .setIsInstantApp(isInstantApp)
                .done(activity, false /* rebindActions */);
    }

}
+4 −41
Original line number Diff line number Diff line
@@ -107,7 +107,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
    private static final int DLG_DISABLE = DLG_BASE + 2;
    private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;

    private static final String KEY_HEADER = "header_view";
    private static final String KEY_ADVANCED_APP_INFO_CATEGORY = "advanced_app_info";

    public static final String ARG_PACKAGE_NAME = "package";
@@ -135,7 +134,6 @@ public class AppInfoDashboardFragment extends DashboardFragment

    private boolean mInitialized;
    private boolean mShowUninstalled;
    private LayoutPreference mHeader;
    private boolean mUpdatedSysApp = false;
    private boolean mDisableAfterUninstall;

@@ -213,6 +211,8 @@ public class AppInfoDashboardFragment extends DashboardFragment

        // The following are controllers for preferences that needs to refresh the preference state
        // when app state changes.
        controllers.add(
                new AppHeaderViewPreferenceController(context, this, packageName, lifecycle));
        controllers.add(new AppStoragePreferenceController(context, this, lifecycle));
        controllers.add(new AppDataUsagePreferenceController(context, this, lifecycle));
        controllers.add(new AppNotificationPreferenceController(context, this));
@@ -275,25 +275,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
        return mPackageInfo;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (mFinishing) {
            return;
        }
        final Activity activity = getActivity();
        mHeader = (LayoutPreference) findPreference(KEY_HEADER);
        EntityHeaderController.newInstance(activity, this, mHeader.findViewById(R.id.entity_header))
                .setRecyclerView(getListView(), getLifecycle())
                .setPackageName(mPackageName)
                .setHasAppInfoLink(false)
                .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
                        EntityHeaderController.ActionType.ACTION_NONE)
                .styleActionBar(activity)
                .bindHeaderButtons();

    }

    @Override
    public void onPackageSizeChanged(String packageName) {
        if (!TextUtils.equals(packageName, mPackageName)) {
@@ -382,22 +363,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
        }
    }

    // Utility method to set application label and icon.
    private void setAppLabelAndIcon(PackageInfo pkgInfo) {
        final View appSnippet = mHeader.findViewById(R.id.entity_header);
        mState.ensureIcon(mAppEntry);
        final Activity activity = getActivity();
        final boolean isInstantApp = AppUtils.isInstant(mPackageInfo.applicationInfo);
        final CharSequence summary =
                isInstantApp ? null : getString(Utils.getInstallationStatus(mAppEntry.info));
        EntityHeaderController.newInstance(activity, this, appSnippet)
                .setLabel(mAppEntry)
                .setIcon(mAppEntry)
                .setSummary(summary)
                .setIsInstantApp(isInstantApp)
                .done(activity, false /* rebindActions */);
    }

    @VisibleForTesting
    boolean shouldShowUninstallForAll(AppEntry appEntry) {
        boolean showIt = true;
@@ -433,11 +398,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
            return false; // onCreate must have failed, make sure to exit
        }


        setAppLabelAndIcon(mPackageInfo);
        mState.ensureIcon(mAppEntry);

        // Update the preference summaries.
        final Activity context = getActivity();
        for (Callback callback : mCallbacks) {
            callback.refreshUi();
        }
@@ -450,7 +413,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
            // All other times: if the app no longer exists then we want
            // to go away.
            try {
                final ApplicationInfo ainfo = context.getPackageManager().getApplicationInfo(
                final ApplicationInfo ainfo = getActivity().getPackageManager().getApplicationInfo(
                        mAppEntry.info.packageName,
                        PackageManager.MATCH_DISABLED_COMPONENTS
                        | PackageManager.MATCH_ANY_USER);
+97 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.appinfo;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.support.v7.preference.PreferenceScreen;
import android.view.View;
import android.widget.TextView;

import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.applications.ApplicationsState;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AppHeaderViewPreferenceControllerTest {

    @Mock
    private AppInfoDashboardFragment mFragment;
    @Mock
    private Activity mActivity;

    private Context mContext;
    private AppHeaderViewPreferenceController mController;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
        when(mFragment.getActivity()).thenReturn(mActivity);
        when(mActivity.getApplicationContext()).thenReturn(mContext);
        mController = new AppHeaderViewPreferenceController(mContext, mFragment, "Package1", null);
    }

    @Test
    public void refreshUi_shouldRefreshButton() {
        final PackageInfo packageInfo = mock(PackageInfo.class);
        final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
        final String appLabel = "App1";
        appEntry.label = appLabel;
        final ApplicationInfo info = new ApplicationInfo();
        info.flags = ApplicationInfo.FLAG_INSTALLED;
        info.enabled = true;
        packageInfo.applicationInfo = info;
        appEntry.info = info;
        when(mFragment.getAppEntry()).thenReturn(appEntry);
        when(mFragment.getPackageInfo()).thenReturn(packageInfo);

        final PreferenceScreen screen = mock(PreferenceScreen.class);
        final LayoutPreference preference = mock(LayoutPreference.class);
        when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
        final View header = mock(View.class);
        when(preference.findViewById(R.id.entity_header)).thenReturn(header);
        final TextView title = mock(TextView.class);
        when(header.findViewById(R.id.entity_header_title)).thenReturn(title);
        final TextView summary = mock(TextView.class);
        when(header.findViewById(R.id.entity_header_summary)).thenReturn(summary);
        mController.displayPreference(screen);

        mController.refreshUi();

        verify(title).setText(appLabel);
        verify(summary).setText(mContext.getString(R.string.installed));
    }

}