diff --git a/res/values/config.xml b/res/values/config.xml index 72fbdf27d5d..218364095f3 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -465,6 +465,9 @@ true + + + false diff --git a/res/values/strings.xml b/res/values/strings.xml index 8bd79071e68..1b83704bd95 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10996,6 +10996,9 @@ Panic button + + Managed by %1$s + Start the emergency SOS actions by pressing the power button quickly 5 times. diff --git a/src/com/android/settings/gestures/PanicGesturePreferenceController.java b/src/com/android/settings/gestures/PanicGesturePreferenceController.java index 947cbb9f8a9..42d3e412e07 100644 --- a/src/com/android/settings/gestures/PanicGesturePreferenceController.java +++ b/src/com/android/settings/gestures/PanicGesturePreferenceController.java @@ -17,10 +17,16 @@ package com.android.settings.gestures; import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.provider.Settings; import android.text.TextUtils; +import android.util.Log; import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; import com.android.settings.R; @@ -28,11 +34,19 @@ import com.android.settings.R; * Preference controller for emergency sos gesture setting */ public class PanicGesturePreferenceController extends GesturePreferenceController { + private static final String TAG = "PanicGesturePreferenceC"; @VisibleForTesting static final int ON = 1; @VisibleForTesting static final int OFF = 0; + @VisibleForTesting + static final String ACTION_PANIC_SETTINGS = + "com.android.settings.action.panic_settings"; + @VisibleForTesting + Intent mIntent; + + private boolean mUseCustomIntent; private static final String PREF_KEY_VIDEO = "panic_button_screen_video"; @@ -40,16 +54,38 @@ public class PanicGesturePreferenceController extends GesturePreferenceControlle public PanicGesturePreferenceController(Context context, String key) { super(context, key); + final String panicSettingsPackageName = context.getResources().getString( + R.string.panic_gesture_settings_package); + if (!TextUtils.isEmpty(panicSettingsPackageName)) { + mUseCustomIntent = true; + // Use custom intent if it's configured and system can resolve it. + final Intent intent = new Intent(ACTION_PANIC_SETTINGS) + .setPackage(panicSettingsPackageName); + if (canResolveIntent(intent)) { + mIntent = intent; + } + } } - private static boolean isGestureAvailable(Context context) { - return context.getResources() - .getBoolean(R.bool.config_show_panic_gesture_settings); + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (TextUtils.equals(getPreferenceKey(), preference.getKey()) && mIntent != null) { + mIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + mContext.startActivity(mIntent); + return true; + } + return super.handlePreferenceTreeClick(preference); } @Override public int getAvailabilityStatus() { - return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + final boolean isConfigEnabled = mContext.getResources() + .getBoolean(R.bool.config_show_panic_gesture_settings); + + if (!isConfigEnabled) { + return UNSUPPORTED_ON_DEVICE; + } + return AVAILABLE; } @Override @@ -57,6 +93,32 @@ public class PanicGesturePreferenceController extends GesturePreferenceControlle return TextUtils.equals(getPreferenceKey(), "gesture_panic_button"); } + @Override + protected boolean canHandleClicks() { + return !mUseCustomIntent || mIntent != null; + } + + @Override + public CharSequence getSummary() { + if (mUseCustomIntent) { + final String packageName = mContext.getResources().getString( + R.string.panic_gesture_settings_package); + try { + final PackageManager pm = mContext.getPackageManager(); + final ApplicationInfo appInfo = pm.getApplicationInfo( + packageName, PackageManager.MATCH_DISABLED_COMPONENTS + | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS); + return mContext.getString(R.string.panic_gesture_entrypoint_summary, + appInfo.loadLabel(pm)); + } catch (Exception e) { + Log.d(TAG, "Failed to get custom summary, falling back."); + return super.getSummary(); + } + } + + return super.getSummary(); + } + @Override protected String getVideoPrefKey() { return PREF_KEY_VIDEO; @@ -72,4 +134,17 @@ public class PanicGesturePreferenceController extends GesturePreferenceControlle return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY, isChecked ? ON : OFF); } + + /** + * Whether or not gesture page content should be suppressed from search. + */ + public boolean shouldSuppressFromSearch() { + return mUseCustomIntent; + } + + private boolean canResolveIntent(Intent intent) { + final ResolveInfo resolveActivity = mContext.getPackageManager() + .resolveActivity(intent, 0); + return resolveActivity != null; + } } diff --git a/src/com/android/settings/gestures/PanicGestureSettings.java b/src/com/android/settings/gestures/PanicGestureSettings.java index c29604776aa..e7f122143c6 100644 --- a/src/com/android/settings/gestures/PanicGestureSettings.java +++ b/src/com/android/settings/gestures/PanicGestureSettings.java @@ -17,6 +17,7 @@ package com.android.settings.gestures; import android.app.settings.SettingsEnums; +import android.content.Context; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; @@ -47,5 +48,14 @@ public class PanicGestureSettings extends DashboardFragment { } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.panic_gesture_settings); + new BaseSearchIndexProvider(R.xml.panic_gesture_settings) { + @Override + protected boolean isPageSearchEnabled(Context context) { + final PanicGesturePreferenceController controller = + new PanicGesturePreferenceController(context, + "dummy_panic_gesture_pref_key"); + return !controller.isAvailable() + || controller.shouldSuppressFromSearch(); + } + }; } diff --git a/tests/robotests/src/com/android/settings/gestures/PanicGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PanicGesturePreferenceControllerTest.java index d071681b05f..f451276c8e4 100644 --- a/tests/robotests/src/com/android/settings/gestures/PanicGesturePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/PanicGesturePreferenceControllerTest.java @@ -23,6 +23,9 @@ import static com.google.common.truth.Truth.assertThat; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ResolveInfo; import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; @@ -35,15 +38,22 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowPackageManager; @RunWith(RobolectricTestRunner.class) @Config(shadows = SettingsShadowResources.class) public class PanicGesturePreferenceControllerTest { + private static final String TEST_PKG_NAME = "test_pkg"; + private static final String TEST_CLASS_NAME = "name"; + private static final Intent SETTING_INTENT = new Intent( + PanicGesturePreferenceController.ACTION_PANIC_SETTINGS).setPackage(TEST_PKG_NAME); private Context mContext; private ContentResolver mContentResolver; + private ShadowPackageManager mPackageManager; private PanicGesturePreferenceController mController; private static final String PREF_KEY = "gesture_panic_button"; @@ -51,6 +61,7 @@ public class PanicGesturePreferenceControllerTest { public void setUp() { mContext = ApplicationProvider.getApplicationContext(); mContentResolver = mContext.getContentResolver(); + mPackageManager = Shadows.shadowOf(mContext.getPackageManager()); mController = new PanicGesturePreferenceController(mContext, PREF_KEY); } @@ -59,6 +70,28 @@ public class PanicGesturePreferenceControllerTest { SettingsShadowResources.reset(); } + @Test + public void constructor_hasCustomPackageConfig_shouldSetIntent() { + final ResolveInfo info = new ResolveInfo(); + info.activityInfo = new ActivityInfo(); + info.activityInfo.packageName = TEST_PKG_NAME; + info.activityInfo.name = TEST_CLASS_NAME; + + mPackageManager.addResolveInfoForIntent(SETTING_INTENT, info); + + SettingsShadowResources.overrideResource( + R.bool.config_show_panic_gesture_settings, + Boolean.TRUE); + + SettingsShadowResources.overrideResource( + R.string.panic_gesture_settings_package, + TEST_PKG_NAME); + + mController = new PanicGesturePreferenceController(mContext, PREF_KEY); + + assertThat(mController.mIntent).isNotNull(); + } + @Test public void isAvailable_configIsTrue_shouldReturnTrue() { SettingsShadowResources.overrideResource(