diff --git a/res/layout/app_details.xml b/res/layout/app_details.xml
index 6b6a5787c41..00d4cca4b34 100644
--- a/res/layout/app_details.xml
+++ b/res/layout/app_details.xml
@@ -87,6 +87,17 @@
android:gravity="start"
android:paddingTop="8dp"/>
+
+
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 01547ef9b31..4df5526ec1b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8220,6 +8220,9 @@
On
+
+ Instant app
+
Games
diff --git a/src/com/android/settings/applications/AppHeaderController.java b/src/com/android/settings/applications/AppHeaderController.java
index 1d64fcae071..45b8960d613 100644
--- a/src/com/android/settings/applications/AppHeaderController.java
+++ b/src/com/android/settings/applications/AppHeaderController.java
@@ -37,7 +37,6 @@ import android.widget.TextView;
import com.android.settings.AppHeader;
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.applications.instantapps.InstantAppDetails;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState;
@@ -81,7 +80,7 @@ public class AppHeaderController {
@ActionType
private int mRightAction;
- private InstantAppDetails mInstantAppDetails;
+ private boolean mIsInstantApp;
public AppHeaderController(Context context, Fragment fragment, View appHeader) {
mContext = context;
@@ -154,8 +153,8 @@ public class AppHeaderController {
return this;
}
- public AppHeaderController setInstantAppDetails(InstantAppDetails instantAppDetails) {
- mInstantAppDetails = instantAppDetails;
+ public AppHeaderController setIsInstantApp(boolean isInstantApp) {
+ this.mIsInstantApp = isInstantApp;
return this;
}
@@ -220,26 +219,9 @@ public class AppHeaderController {
bindAppHeaderButtons();
}
- if (mInstantAppDetails != null) {
- setText(R.id.instant_app_developer_title, mInstantAppDetails.developerTitle);
- View maturity = mAppHeader.findViewById(R.id.instant_app_maturity);
-
- if (maturity != null) {
- String maturityText = mInstantAppDetails.maturityRatingString;
- Drawable maturityIcon = mInstantAppDetails.maturityRatingIcon;
- if (!TextUtils.isEmpty(maturityText) || maturityIcon != null) {
- maturity.setVisibility(View.VISIBLE);
- }
- setText(R.id.instant_app_maturity_text, maturityText);
- if (maturityIcon != null) {
- ImageView maturityIconView = (ImageView) mAppHeader.findViewById(
- R.id.instant_app_maturity_icon);
- if (maturityIconView != null) {
- maturityIconView.setImageDrawable(maturityIcon);
- }
- }
- }
- setText(R.id.instant_app_monetization, mInstantAppDetails.monetizationNotice);
+ if (mIsInstantApp) {
+ setText(R.id.install_type,
+ mAppHeader.getResources().getString(R.string.install_type_instant));
}
return mAppHeader;
diff --git a/src/com/android/settings/applications/AppInfoWithHeader.java b/src/com/android/settings/applications/AppInfoWithHeader.java
index 910b618b04f..4f3e8faeb98 100644
--- a/src/com/android/settings/applications/AppInfoWithHeader.java
+++ b/src/com/android/settings/applications/AppInfoWithHeader.java
@@ -23,6 +23,7 @@ import android.util.Log;
import com.android.settings.AppHeader;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.applications.AppUtils;
import static com.android.settings.applications.AppHeaderController.ActionType;
@@ -52,6 +53,7 @@ public abstract class AppInfoWithHeader extends AppInfoBase {
.setIcon(mPackageInfo.applicationInfo.loadIcon(mPm))
.setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
.setSummary(mPackageInfo)
+ .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
.setPackageName(mPackageName)
.setUid(mPackageInfo.applicationInfo.uid)
.setButtonActions(ActionType.ACTION_APP_INFO, ActionType.ACTION_NONE)
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 0be4d9e8614..581b0aff486 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -563,6 +563,7 @@ public class InstalledAppDetails extends AppInfoBase
.setLabel(mAppEntry)
.setIcon(mAppEntry)
.setSummary(getString(getInstallationStatus(mAppEntry.info)))
+ .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
.done(false /* rebindActions */);
mVersionPreference.setSummary(getString(R.string.version_text, pkgInfo.versionName));
} else {
diff --git a/src/com/android/settings/applications/instantapps/InstantAppDetails.java b/src/com/android/settings/applications/instantapps/InstantAppDetails.java
deleted file mode 100644
index 8b54c207f1f..00000000000
--- a/src/com/android/settings/applications/instantapps/InstantAppDetails.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.instantapps;
-
-import android.graphics.drawable.Drawable;
-import java.net.URL;
-
-/**
- * Encapsulates state about instant apps that is provided by an app store implementation.
- */
-public class InstantAppDetails {
-
- // Most of these members are self-explanatory; the one that may not be is
- // monetizationNotice, which is a string alerting users that the app contains ads and/or uses
- // in-app purchases (this may eventually become two separate members).
- public final Drawable maturityRatingIcon;
- public final String maturityRatingString;
- public final String monetizationNotice;
- public final String developerTitle;
- public final URL privacyPolicy;
- public final URL developerWebsite;
- public final String developerEmail;
- public final String developerMailingAddress;
-
- public static class Builder {
- private Drawable mMaturityRatingIcon;
- private String mMaturityRatingString;
- private String mMonetizationNotice;
- private String mDeveloperTitle;
- private URL mPrivacyPolicy;
- private URL mDeveloperWebsite;
- private String mDeveloperEmail;
- private String mDeveloperMailingAddress;
-
- public Builder maturityRatingIcon(Drawable maturityRatingIcon) {
- this.mMaturityRatingIcon = maturityRatingIcon;
- return this;
- }
-
- public Builder maturityRatingString(String maturityRatingString) {
- mMaturityRatingString = maturityRatingString;
- return this;
- }
-
- public Builder monetizationNotice(String monetizationNotice) {
- mMonetizationNotice = monetizationNotice;
- return this;
- }
-
- public Builder developerTitle(String developerTitle) {
- mDeveloperTitle = developerTitle;
- return this;
- }
-
- public Builder privacyPolicy(URL privacyPolicy) {
- mPrivacyPolicy = privacyPolicy;
- return this;
- }
-
- public Builder developerWebsite(URL developerWebsite) {
- mDeveloperWebsite = developerWebsite;
- return this;
- }
-
- public Builder developerEmail(String developerEmail) {
- mDeveloperEmail = developerEmail;
- return this;
- }
-
- public Builder developerMailingAddress(String developerMailingAddress) {
- mDeveloperMailingAddress = developerMailingAddress;
- return this;
- }
-
- public InstantAppDetails build() {
- return new InstantAppDetails(mMaturityRatingIcon, mMaturityRatingString,
- mMonetizationNotice, mDeveloperTitle, mPrivacyPolicy, mDeveloperWebsite,
- mDeveloperEmail, mDeveloperMailingAddress);
- }
- }
-
- public static Builder builder() { return new Builder(); }
-
- private InstantAppDetails(Drawable maturityRatingIcon, String maturityRatingString,
- String monetizationNotice, String developerTitle, URL privacyPolicy,
- URL developerWebsite, String developerEmail, String developerMailingAddress) {
- this.maturityRatingIcon = maturityRatingIcon;
- this.maturityRatingString = maturityRatingString;
- this.monetizationNotice = monetizationNotice;
- this.developerTitle = developerTitle;
- this.privacyPolicy = privacyPolicy;
- this.developerWebsite = developerWebsite;
- this.developerEmail = developerEmail;
- this.developerMailingAddress = developerMailingAddress;
- }
-}
diff --git a/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java b/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java
index 3ee33aa0d86..bd55fd05e8a 100644
--- a/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java
@@ -36,8 +36,6 @@ import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
-import com.android.settings.applications.InstantDataBuilder.Param;
-import com.android.settings.applications.instantapps.InstantAppDetails;
import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
@@ -271,102 +269,27 @@ public class AppHeaderControllerTest {
.isEqualTo(View.GONE);
}
- // Ensure that no instant app related information shows up when the AppHeaderController's
- // InstantAppDetails are null.
+ // Ensure that the instant app label does not show up when we haven't told the controller the
+ // app is instant.
@Test
- public void instantApps_nullInstantAppDetails() {
+ public void instantApps_normalAppsDontGetLabel() {
final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
mController = new AppHeaderController(mContext, mFragment, appHeader);
- mController.setInstantAppDetails(null);
mController.done();
- assertThat(appHeader.findViewById(R.id.instant_app_developer_title).getVisibility())
- .isEqualTo(View.GONE);
- assertThat(appHeader.findViewById(R.id.instant_app_maturity).getVisibility())
- .isEqualTo(View.GONE);
- assertThat(appHeader.findViewById(R.id.instant_app_monetization).getVisibility())
+ assertThat(appHeader.findViewById(R.id.install_type).getVisibility())
.isEqualTo(View.GONE);
}
- // Ensure that no instant app related information shows up when the AppHeaderController has
- // a non-null InstantAppDetails, but each member of it is null.
+ // Test that the "instant apps" label is present in the header when we have an instant app.
@Test
- public void instantApps_detailsMembersNull() {
+ public void instantApps_expectedHeaderItem() {
final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
mController = new AppHeaderController(mContext, mFragment, appHeader);
-
- InstantAppDetails details = InstantDataBuilder.build(mContext, EnumSet.noneOf(Param.class));
- mController.setInstantAppDetails(details);
+ mController.setIsInstantApp(true);
mController.done();
- assertThat(appHeader.findViewById(R.id.instant_app_developer_title).getVisibility())
- .isEqualTo(View.GONE);
- assertThat(appHeader.findViewById(R.id.instant_app_maturity).getVisibility())
- .isEqualTo(View.GONE);
- assertThat(appHeader.findViewById(R.id.instant_app_monetization).getVisibility())
- .isEqualTo(View.GONE);
- }
-
- // Helper to assert a TextView for a given id is visible and has a certain string value.
- private void assertVisibleContent(View header, @IdRes int id, String expectedValue) {
- TextView view = (TextView)header.findViewById(id);
- assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(view.getText()).isEqualTo(expectedValue);
- }
-
- // Helper to assert an ImageView for a given id is visible and has a certain Drawable value.
- private void assertVisibleContent(View header, @IdRes int id, Drawable expectedValue) {
- ImageView view = (ImageView)header.findViewById(id);
- assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(view.getDrawable()).isEqualTo(expectedValue);
- }
-
- // Test that expected items are present in the header when we have a complete InstantAppDetails.
- @Test
- public void instantApps_expectedHeaderItems() {
- final View header = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
- mController = new AppHeaderController(mContext, mFragment, header);
-
- InstantAppDetails details = InstantDataBuilder.build(mContext);
- mController.setInstantAppDetails(details);
- mController.done();
-
- assertVisibleContent(header, R.id.instant_app_developer_title, details.developerTitle);
- assertVisibleContent(header, R.id.instant_app_maturity_icon,
- details.maturityRatingIcon);
- assertVisibleContent(header, R.id.instant_app_maturity_text,
- details.maturityRatingString);
- assertVisibleContent(header, R.id.instant_app_monetization,
- details.monetizationNotice);
- }
-
- // Test having each member of InstantAppDetails be null.
- @Test
- public void instantApps_expectedHeaderItemsWithSingleNullMembers() {
- final EnumSet allParams = EnumSet.allOf(Param.class);
- for (Param paramToRemove : allParams) {
- EnumSet params = allParams.clone();
- params.remove(paramToRemove);
- final View header = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
- mController = new AppHeaderController(mContext, mFragment, header);
- InstantAppDetails details = InstantDataBuilder.build(mContext, params);
- mController.setInstantAppDetails(details);
- mController.done();
-
- if (params.contains(Param.DEVELOPER_TITLE)) {
- assertVisibleContent(header, R.id.instant_app_developer_title,
- details.developerTitle);
- }
- if (params.contains(Param.MATURITY_RATING_ICON)) {
- assertVisibleContent(header, R.id.instant_app_maturity_icon,
- details.maturityRatingIcon);
- }
- if (params.contains(Param.MATURITY_RATING_STRING)) {
- assertVisibleContent(header, R.id.instant_app_maturity_text,
- details.maturityRatingString);
- }
- if (params.contains(Param.MONETIZATION_NOTICE)) {
- assertVisibleContent(header, R.id.instant_app_monetization,
- details.monetizationNotice);
- }
- }
+ TextView label = (TextView)appHeader.findViewById(R.id.install_type);
+ assertThat(label.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(label.getText()).isEqualTo(
+ appHeader.getResources().getString(R.string.install_type_instant));
}
}
diff --git a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
index 4cc39fb40c2..56d4a83f325 100644
--- a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
@@ -28,6 +28,8 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
import org.junit.Before;
import org.junit.Test;
@@ -37,6 +39,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
@@ -88,7 +91,8 @@ public class AppInfoWithHeaderTest {
mScreen = mock(PreferenceScreen.class);
mPackageInfo = new PackageInfo();
mPackageInfo.applicationInfo = new ApplicationInfo();
-
+ ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+ (InstantAppDataProvider) (info -> false));
when(mManager.getContext())
.thenReturn(ShadowApplication.getInstance().getApplicationContext());
}
diff --git a/tests/robotests/src/com/android/settings/applications/InstantDataBuilder.java b/tests/robotests/src/com/android/settings/applications/InstantDataBuilder.java
deleted file mode 100644
index 81ebe06e11e..00000000000
--- a/tests/robotests/src/com/android/settings/applications/InstantDataBuilder.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * 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;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.Nullable;
-
-import com.android.settings.R;
-import com.android.settings.applications.instantapps.InstantAppDetails;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.EnumSet;
-
-/**
- * Utility class for generating fake InstantAppDetails data to use in tests.
- */
-public class InstantDataBuilder {
- public enum Param {
- MATURITY_RATING_ICON,
- MATURITY_RATING_STRING,
- MONETIZATION_NOTICE,
- DEVELOPER_TITLE,
- PRIVACY_POLICY,
- DEVELOPER_WEBSITE,
- DEVELOPER_EMAIL,
- DEVELOPER_MAILING_ADDRESS
- }
-
- /**
- * Creates an InstantAppDetails with any desired combination of null/non-null members.
- *
- * @param context An optional context, required only if MATURITY_RATING_ICON is a member of
- * params
- * @param params Specifies which elements of the returned InstantAppDetails should be non-null
- * @return InstantAppDetails
- */
- public static InstantAppDetails build(@Nullable Context context, EnumSet params) {
- Drawable ratingIcon = null;
- String rating = null;
- String monetizationNotice = null;
- String developerTitle = null;
- URL privacyPolicy = null;
- URL developerWebsite = null;
- String developerEmail = null;
- String developerMailingAddress = null;
-
- if (params.contains(Param.MATURITY_RATING_ICON)) {
- ratingIcon = context.getDrawable(R.drawable.ic_android);
- }
- if (params.contains(Param.MATURITY_RATING_STRING)) {
- rating = "everyone";
- }
- if (params.contains(Param.MONETIZATION_NOTICE)) {
- monetizationNotice = "Uses in-app purchases";
- }
- if (params.contains(Param.DEVELOPER_TITLE)) {
- developerTitle = "Instant Apps Inc.";
- }
- if (params.contains(Param.DEVELOPER_EMAIL)) {
- developerEmail = "developer@instant-apps.com";
- }
- if (params.contains(Param.DEVELOPER_MAILING_ADDRESS)) {
- developerMailingAddress = "1 Main Street, Somewhere, CA, 94043";
- }
-
- if (params.contains(Param.PRIVACY_POLICY)) {
- try {
- privacyPolicy = new URL("https://test.com/privacy");
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
- if (params.contains(Param.DEVELOPER_WEBSITE)) {
- try {
- developerWebsite = new URL("https://test.com");
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
- return InstantAppDetails.builder()
- .maturityRatingIcon(ratingIcon)
- .maturityRatingString(rating)
- .monetizationNotice(monetizationNotice)
- .developerTitle(developerTitle)
- .privacyPolicy(privacyPolicy)
- .developerWebsite(developerWebsite)
- .developerEmail(developerEmail)
- .developerMailingAddress(developerMailingAddress)
- .build();
- }
-
- /**
- * Convenience method to create an InstantAppDetails with all non-null members.
- *
- * @param context a required Context for loading a test maturity rating icon
- * @return InstantAppDetails
- */
- public static InstantAppDetails build(Context context) {
- return build(context, EnumSet.allOf(Param.class));
- }
-}