Loading src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java 0 → 100644 +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 */); } } src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +4 −41 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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(); } Loading @@ -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); Loading tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java 0 → 100644 +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)); } } Loading
src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java 0 → 100644 +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 */); } }
src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +4 −41 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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(); } Loading @@ -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); Loading
tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java 0 → 100644 +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)); } }