Remove NewDeviceIntroSuggestion

The functionality is entirely replaced by other apps.

Change-Id: Id3d425cf92a07bae070cd22c0d726aba0472dd5d
Fixes: 111195449
Test: robotest
This commit is contained in:
Fan Zhang
2018-07-12 10:58:13 -07:00
parent 00d42c510d
commit 5c3816ba03
9 changed files with 18 additions and 394 deletions

View File

@@ -824,22 +824,6 @@
<meta-data android:name="com.android.settings.icon_tintable" android:value="true" />
</activity>
<activity android:name=".support.NewDeviceIntroSuggestionActivity"
android:label="@string/new_device_suggestion_title"
android:icon="@drawable/ic_new_device_suggestion_24dp"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.android.settings.suggested.category.FIRST_IMPRESSION" />
</intent-filter>
<meta-data android:name="com.android.settings.dismiss"
android:value="0,4" />
<meta-data android:name="com.android.settings.title"
android:resource="@string/new_device_suggestion_title" />
<meta-data android:name="com.android.settings.summary"
android:resource="@string/new_device_suggestion_summary" />
</activity>
<activity
android:name="Settings$ZenModeScheduleRuleSettingsActivity"
android:exported="true"

View File

@@ -1,26 +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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
android:tint="?android:attr/colorControlNormal">
<path android:fillColor="#FF000000"
android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z" />
</vector>

View File

@@ -117,9 +117,6 @@
<!-- Class name for the storage manager's deletion helper class. -->
<string name="config_deletion_helper_class" translatable="false">com.android.storagemanager.deletionhelper.DeletionHelperActivity</string>
<!-- Whether or not new device intro suggestion is supported for this device -->
<bool name="config_new_device_intro_suggestion_supported">false</bool>
<!-- Whether to use a UI variant that minimizes the number of UI elements on screen. This is
typically used when there is not enough space to display everything, because pattern view
doesn't interact well with scroll view -->

View File

@@ -10007,18 +10007,6 @@
<!-- Summary label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
<string name="zen_suggestion_summary">Pause notifications to stay focused</string>
<!-- Title label for new device suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
<string name="new_device_suggestion_title">What\'s new and exciting?</string>
<!-- Summary label for new device suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
<string name="new_device_suggestion_summary" product="default">Take a tour of your new phone</string>
<!-- Summary label for new device suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
<string name="new_device_suggestion_summary" product="tablet">Take a tour of your new tablet</string>
<!-- Summary label for new device suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
<string name="new_device_suggestion_summary" product="device">Take a tour of your new device</string>
<!-- The divider symbol between different parts of the notification header including spaces. not translatable [CHAR LIMIT=3] -->
<string name="notification_header_divider_symbol_with_spaces" translatable="false">" • "</string>

View File

@@ -34,7 +34,6 @@ import com.android.settings.notification.ZenOnboardingActivity;
import com.android.settings.notification.ZenSuggestionActivity;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ScreenLockSuggestionActivity;
import com.android.settings.support.NewDeviceIntroSuggestionActivity;
import com.android.settings.wallpaper.WallpaperSuggestionActivity;
import com.android.settings.wifi.calling.WifiCallingSuggestionActivity;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -88,8 +87,6 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider
return WifiCallingSuggestionActivity.isSuggestionComplete(context);
} else if (className.equals(NightDisplaySuggestionActivity.class.getName())) {
return NightDisplayPreferenceController.isSuggestionComplete(context);
} else if (className.equals(NewDeviceIntroSuggestionActivity.class.getName())) {
return NewDeviceIntroSuggestionActivity.isSuggestionComplete(context);
} else if (className.equals(ZenSuggestionActivity.class.getName())) {
return ZenOnboardingActivity.isSuggestionComplete(context);
}

View File

@@ -1,155 +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.support;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import com.android.settings.R;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.overlay.SupportFeatureProvider;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
public class NewDeviceIntroSuggestionActivity extends Activity {
private static final String TAG = "NewDeviceIntroSugg";
@VisibleForTesting
static final String PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME =
"pref_new_device_intro_suggestion_first_display_time_ms";
@VisibleForTesting
static final String PREF_KEY_SUGGGESTION_COMPLETE =
"pref_new_device_intro_suggestion_complete";
@VisibleForTesting
static final long PERMANENT_DISMISS_THRESHOLD = DateUtils.DAY_IN_MILLIS * 14;
public static final String TIPS_PACKAGE_NAME = "com.google.android.apps.tips";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getLaunchIntent(this);
if (intent != null) {
final SuggestionFeatureProvider featureProvider = FeatureFactory.getFactory(this)
.getSuggestionFeatureProvider(this);
final SharedPreferences prefs = featureProvider.getSharedPrefs(this);
prefs.edit().putBoolean(PREF_KEY_SUGGGESTION_COMPLETE, true).commit();
startActivity(intent);
}
finish();
}
public static boolean isSuggestionComplete(Context context) {
// Always returns 'true' if Tips application exists. Check b/77652536 for more details.
return isTipsInstalledAsSystemApp(context)
|| !isSupported(context)
|| isExpired(context)
|| hasLaunchedBefore(context)
|| !canOpenUrlInBrowser(context);
}
private static boolean isSupported(Context context) {
return context.getResources()
.getBoolean(R.bool.config_new_device_intro_suggestion_supported);
}
private static boolean isExpired(Context context) {
final SuggestionFeatureProvider featureProvider = FeatureFactory.getFactory(context)
.getSuggestionFeatureProvider(context);
final SharedPreferences prefs = featureProvider.getSharedPrefs(context);
final long currentTimeMs = System.currentTimeMillis();
final long firstDisplayTimeMs;
if (!prefs.contains(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME)) {
firstDisplayTimeMs = currentTimeMs;
prefs.edit().putLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME, currentTimeMs).commit();
} else {
firstDisplayTimeMs = prefs.getLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME, -1);
}
final long dismissTimeMs = firstDisplayTimeMs + PERMANENT_DISMISS_THRESHOLD;
final boolean expired = currentTimeMs > dismissTimeMs;
Log.d(TAG, "is suggestion expired: " + expired);
return expired;
}
private static boolean canOpenUrlInBrowser(Context context) {
final Intent intent = getLaunchIntent(context);
if (intent == null) {
// No url/intent to launch.
return false;
}
// Make sure we can handle the intent.
final List<ResolveInfo> resolveInfos =
context.getPackageManager().queryIntentActivities(intent, 0);
return resolveInfos != null && resolveInfos.size() != 0;
}
private static boolean hasLaunchedBefore(Context context) {
final SuggestionFeatureProvider featureProvider = FeatureFactory.getFactory(context)
.getSuggestionFeatureProvider(context);
final SharedPreferences prefs = featureProvider.getSharedPrefs(context);
return prefs.getBoolean(PREF_KEY_SUGGGESTION_COMPLETE, false);
}
@VisibleForTesting
static Intent getLaunchIntent(Context context) {
final SupportFeatureProvider supportProvider = FeatureFactory.getFactory(context)
.getSupportFeatureProvider(context);
if (supportProvider == null) {
return null;
}
final String url = supportProvider.getNewDeviceIntroUrl(context);
if (TextUtils.isEmpty(url)) {
return null;
}
return new Intent()
.setAction(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.parse(url));
}
/**
* Check if the specified package exists and is marked with <i>FLAG_SYSTEM</i>
*/
private static boolean isTipsInstalledAsSystemApp(@NonNull Context context) {
try {
final PackageInfo info = context.getPackageManager().getPackageInfo(TIPS_PACKAGE_NAME,
PackageManager.MATCH_SYSTEM_ONLY);
return info != null;
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Cannot find the package: " + TIPS_PACKAGE_NAME, e);
return false;
}
}
}

View File

@@ -16,7 +16,6 @@
<resources>
<!-- Whether or not new device intro suggestion is supported for this device -->
<bool name="config_new_device_intro_suggestion_supported">true</bool>
<bool name="config_enableColorTemperature">true</bool>
<bool name="config_show_camera_laser_sensor">true</bool>
<bool name="config_show_connectivity_monitor">true</bool>

View File

@@ -31,7 +31,6 @@ import com.android.settings.Settings;
import com.android.settings.biometrics.fingerprint.FingerprintEnrollSuggestionActivity;
import com.android.settings.biometrics.fingerprint.FingerprintSuggestionActivity;
import com.android.settings.notification.ZenSuggestionActivity;
import com.android.settings.support.NewDeviceIntroSuggestionActivity;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wallpaper.WallpaperSuggestionActivity;
import com.android.settings.wifi.calling.WifiCallingSuggestionActivity;
@@ -91,14 +90,6 @@ public class SettingsSuggestionsTest {
R.string.zen_suggestion_summary);
}
@Test
public void newDeviceIntroSuggestion_isValid() {
assertSuggestionEquals(
NewDeviceIntroSuggestionActivity.class.getName(),
R.string.new_device_suggestion_title,
R.string.new_device_suggestion_summary);
}
private void assertSuggestionEquals(String activityName, @StringRes int titleRes,
@StringRes int summaryRes) {

View File

@@ -1,151 +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.support;
import static com.android.settings.support.NewDeviceIntroSuggestionActivity.PERMANENT_DISMISS_THRESHOLD;
import static com.android.settings.support.NewDeviceIntroSuggestionActivity.PREF_KEY_SUGGGESTION_COMPLETE;
import static com.android.settings.support.NewDeviceIntroSuggestionActivity.PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME;
import static com.android.settings.support.NewDeviceIntroSuggestionActivity.TIPS_PACKAGE_NAME;
import static com.android.settings.support.NewDeviceIntroSuggestionActivity.isSuggestionComplete;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowPackageManager;
@RunWith(SettingsRobolectricTestRunner.class)
public class NewDeviceIntroSuggestionActivityTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mMockContext;
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
private ShadowPackageManager mShadowPackageManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mFeatureFactory.suggestionsFeatureProvider.getSharedPrefs(any(Context.class)))
.thenReturn(getSharedPreferences());
}
@Test
public void isSuggestionComplete_TipsNotExistsAndNotExpiredAndCanOpenUrl_shouldReturnFalse() {
mShadowPackageManager.removePackage(TIPS_PACKAGE_NAME);
when(mMockContext.getResources()
.getBoolean(R.bool.config_new_device_intro_suggestion_supported))
.thenReturn(true);
when(mFeatureFactory.supportFeatureProvider.getNewDeviceIntroUrl(any(Context.class)))
.thenReturn("https://com.android.settings");
final Intent intent = NewDeviceIntroSuggestionActivity.getLaunchIntent(mContext);
mShadowPackageManager.addResolveInfoForIntent(intent, new ResolveInfo());
assertThat(isSuggestionComplete(mContext)).isFalse();
}
@Test
public void isSuggestionComplete_TipsExistsAndNotExpiredAndCanOpenUrl_shouldReturnTrue() {
final PackageInfo mockInfo = new PackageInfo();
mockInfo.packageName = TIPS_PACKAGE_NAME;
mShadowPackageManager.addPackage(mockInfo);
when(mMockContext.getResources()
.getBoolean(R.bool.config_new_device_intro_suggestion_supported))
.thenReturn(true);
when(mFeatureFactory.supportFeatureProvider.getNewDeviceIntroUrl(any(Context.class)))
.thenReturn("https://com.android.settings");
final Intent intent = NewDeviceIntroSuggestionActivity.getLaunchIntent(mContext);
mShadowPackageManager.addResolveInfoForIntent(intent, new ResolveInfo());
assertThat(isSuggestionComplete(mContext)).isTrue();
}
@Test
public void isSuggestionComplete_notSupported_shouldReturnTrue() {
when(mMockContext.getResources()
.getBoolean(R.bool.config_new_device_intro_suggestion_supported))
.thenReturn(false);
assertThat(isSuggestionComplete(mContext)).isTrue();
}
@Test
public void isSuggestionComplete_suggestionExpired_shouldReturnTrue() {
final long currentTime = System.currentTimeMillis();
getSharedPreferences().edit().putLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME,
currentTime - 2 * PERMANENT_DISMISS_THRESHOLD).commit();
assertThat(isSuggestionComplete(mContext)).isTrue();
}
@Test
public void isSuggestionComplete_noUrl_shouldReturnTrue() {
when(mFeatureFactory.supportFeatureProvider.getNewDeviceIntroUrl(any(Context.class)))
.thenReturn(null);
assertThat(isSuggestionComplete(mContext)).isTrue();
}
@Test
public void isSuggestionComplete_alreadyLaunchedBefore_shouldReturnTrue() {
when(mFeatureFactory.supportFeatureProvider.getNewDeviceIntroUrl(any(Context.class)))
.thenReturn("https://com.android.settings");
getSharedPreferences().edit().putBoolean(PREF_KEY_SUGGGESTION_COMPLETE, true).commit();
assertThat(isSuggestionComplete(mContext)).isTrue();
}
@Test
public void isSuggestionComplete_notExpiredAndCanOpenUrlInBrowser_shouldReturnFalse() {
when(mFeatureFactory.supportFeatureProvider.getNewDeviceIntroUrl(any(Context.class)))
.thenReturn("https://com.android.settings");
final Intent intent = NewDeviceIntroSuggestionActivity.getLaunchIntent(mContext);
mShadowPackageManager.addResolveInfoForIntent(intent, new ResolveInfo());
assertThat(isSuggestionComplete(mContext)).isFalse();
}
private SharedPreferences getSharedPreferences() {
return mContext.getSharedPreferences("test_new_device_sugg", Context.MODE_PRIVATE);
}
}