Bug: 391672253 Flag: com.android.graphics.hwui.flags.high_contrast_text_small_text_rect Test: Ensure dismissing a notification from open settings does not trigger multiple counter increments Change-Id: I6ddccd40427cf2364d3fb5df4efaa0b16db26133
196 lines
9.2 KiB
Java
196 lines
9.2 KiB
Java
/*
|
|
* Copyright (C) 2024 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.accessibility;
|
|
|
|
import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
|
|
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS;
|
|
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
|
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
|
|
|
import android.annotation.IntDef;
|
|
import android.app.Notification;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationManager;
|
|
import android.app.PendingIntent;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.provider.Settings;
|
|
import android.util.Log;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import com.android.graphics.hwui.flags.Flags;
|
|
import com.android.modules.expresslog.Counter;
|
|
import com.android.settings.R;
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
|
|
/**
|
|
* Handling smooth migration to the new high contrast text appearance
|
|
*/
|
|
public class HighContrastTextMigrationReceiver extends BroadcastReceiver {
|
|
private static final String TAG = HighContrastTextMigrationReceiver.class.getSimpleName();
|
|
@VisibleForTesting
|
|
static final String NOTIFICATION_CHANNEL = "accessibility_notification_channel";
|
|
@VisibleForTesting
|
|
static final String ACTION_RESTORED =
|
|
"com.android.settings.accessibility.ACTION_HIGH_CONTRAST_TEXT_RESTORED";
|
|
@VisibleForTesting
|
|
static final String ACTION_OPEN_SETTINGS =
|
|
"com.android.settings.accessibility.ACTION_OPEN_HIGH_CONTRAST_TEXT_SETTINGS";
|
|
private static final String ACTION_NOTIFICATION_DISMISSED =
|
|
"com.android.settings.accessibility.ACTION_HIGH_CONTRAST_TEXT_NOTIFICATION_DISMISSED";
|
|
@VisibleForTesting
|
|
static final int NOTIFICATION_ID = R.string.accessibility_notification_high_contrast_text_title;
|
|
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@IntDef({
|
|
PromptState.UNKNOWN,
|
|
PromptState.PROMPT_SHOWN,
|
|
PromptState.PROMPT_UNNECESSARY,
|
|
})
|
|
public @interface PromptState {
|
|
int UNKNOWN = 0;
|
|
int PROMPT_SHOWN = 1;
|
|
int PROMPT_UNNECESSARY = 2;
|
|
}
|
|
|
|
@Override
|
|
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
|
|
if (!Flags.highContrastTextSmallTextRect()) {
|
|
return;
|
|
}
|
|
|
|
if (ACTION_OPEN_SETTINGS.equals(intent.getAction())) {
|
|
// Close notification drawer before opening the HCT setting.
|
|
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
|
|
|
|
Intent settingsIntent = createHighContrastTextSettingsIntent(context);
|
|
settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
context.startActivity(settingsIntent);
|
|
|
|
context.getSystemService(NotificationManager.class).cancel(NOTIFICATION_ID);
|
|
} else if (ACTION_NOTIFICATION_DISMISSED.equals(intent.getAction())) {
|
|
Counter.logIncrement("accessibility.value_hct_notification_dismissed");
|
|
} else if (ACTION_RESTORED.equals(intent.getAction())) {
|
|
Log.i(TAG, "HCT attempted to be restored from backup; showing notification for userId: "
|
|
+ context.getUserId());
|
|
Settings.Secure.putInt(context.getContentResolver(),
|
|
Settings.Secure.ACCESSIBILITY_HCT_RECT_PROMPT_STATUS,
|
|
PromptState.PROMPT_SHOWN);
|
|
showNotification(context);
|
|
} else if (Intent.ACTION_PRE_BOOT_COMPLETED.equals(intent.getAction())) {
|
|
final boolean hasSeenPromptIfNecessary = Settings.Secure.getInt(
|
|
context.getContentResolver(),
|
|
Settings.Secure.ACCESSIBILITY_HCT_RECT_PROMPT_STATUS, PromptState.UNKNOWN)
|
|
!= PromptState.UNKNOWN;
|
|
if (hasSeenPromptIfNecessary) {
|
|
Log.i(TAG, "Has seen HCT prompt if necessary; skip HCT migration for userId: "
|
|
+ context.getUserId());
|
|
return;
|
|
}
|
|
|
|
final boolean isHctEnabled = Settings.Secure.getInt(context.getContentResolver(),
|
|
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, OFF) == ON;
|
|
if (isHctEnabled) {
|
|
Log.i(TAG, "HCT enabled before OTA update; performing migration for userId: "
|
|
+ context.getUserId());
|
|
Settings.Secure.putInt(context.getContentResolver(),
|
|
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
|
|
OFF);
|
|
Settings.Secure.putInt(context.getContentResolver(),
|
|
Settings.Secure.ACCESSIBILITY_HCT_RECT_PROMPT_STATUS,
|
|
PromptState.PROMPT_SHOWN);
|
|
showNotification(context);
|
|
} else {
|
|
Log.i(TAG,
|
|
"HCT was not enabled before OTA update; not performing migration for "
|
|
+ "userId: " + context.getUserId());
|
|
Settings.Secure.putInt(context.getContentResolver(),
|
|
Settings.Secure.ACCESSIBILITY_HCT_RECT_PROMPT_STATUS,
|
|
PromptState.PROMPT_UNNECESSARY);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void showNotification(Context context) {
|
|
Notification.Builder notificationBuilder = new Notification.Builder(context,
|
|
NOTIFICATION_CHANNEL)
|
|
.setSmallIcon(R.drawable.ic_settings_24dp)
|
|
.setContentTitle(context.getString(
|
|
R.string.accessibility_notification_high_contrast_text_title))
|
|
.setContentText(context.getString(
|
|
R.string.accessibility_notification_high_contrast_text_content))
|
|
.setFlag(Notification.FLAG_NO_CLEAR, true);
|
|
|
|
Intent settingsIntent = createHighContrastTextSettingsIntent(context);
|
|
if (settingsIntent.resolveActivity(context.getPackageManager()) != null) {
|
|
PendingIntent settingsPendingIntent = PendingIntent.getActivity(context,
|
|
/* requestCode = */ 0, settingsIntent, PendingIntent.FLAG_IMMUTABLE);
|
|
|
|
Intent actionIntent = new Intent(context, HighContrastTextMigrationReceiver.class);
|
|
actionIntent.setAction(ACTION_OPEN_SETTINGS);
|
|
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0,
|
|
actionIntent, PendingIntent.FLAG_IMMUTABLE);
|
|
Notification.Action settingsAction = new Notification.Action.Builder(
|
|
/* icon= */ null,
|
|
context.getString(
|
|
R.string.accessibility_notification_high_contrast_text_action),
|
|
actionPendingIntent
|
|
).build();
|
|
|
|
notificationBuilder
|
|
.setContentIntent(settingsPendingIntent)
|
|
.addAction(settingsAction)
|
|
.setAutoCancel(true);
|
|
}
|
|
|
|
Intent deleteIntent = new Intent(context, HighContrastTextMigrationReceiver.class);
|
|
deleteIntent.setAction(ACTION_NOTIFICATION_DISMISSED);
|
|
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(context, 0,
|
|
deleteIntent, PendingIntent.FLAG_IMMUTABLE);
|
|
notificationBuilder.setDeleteIntent(deletePendingIntent);
|
|
|
|
NotificationManager notificationManager =
|
|
context.getSystemService(NotificationManager.class);
|
|
NotificationChannel notificationChannel = new NotificationChannel(
|
|
NOTIFICATION_CHANNEL,
|
|
context.getString(R.string.accessibility_settings),
|
|
NotificationManager.IMPORTANCE_LOW);
|
|
notificationManager.createNotificationChannel(notificationChannel);
|
|
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
|
|
Counter.logIncrement("accessibility.value_hct_notification_posted");
|
|
}
|
|
|
|
private Intent createHighContrastTextSettingsIntent(Context context) {
|
|
Intent settingsIntent = new Intent(Settings.ACTION_TEXT_READING_SETTINGS);
|
|
settingsIntent.setPackage(context.getPackageName());
|
|
Bundle fragmentArgs = new Bundle();
|
|
fragmentArgs.putString(EXTRA_FRAGMENT_ARG_KEY,
|
|
TextReadingPreferenceFragment.HIGH_TEXT_CONTRAST_KEY);
|
|
fragmentArgs.putInt(TextReadingPreferenceFragment.EXTRA_LAUNCHED_FROM,
|
|
TextReadingPreferenceFragment.EntryPoint.HIGH_CONTRAST_TEXT_NOTIFICATION);
|
|
settingsIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs);
|
|
return settingsIntent;
|
|
}
|
|
}
|