Files
app_Settings/src/com/android/settings/display/CustomizableLockScreenUtils.java
Alejandro Nijamkin 6f9f3a4594 Fixes nav stack issue.
By marking the Intent that's being sent to WPP as "launched from
settings", the code in CustomizationPickerActivity can correctly
conclude that the multi-pane wrapper does not need to be applied to the
intent, preventing the odd "disordering" of the back stack in the bug.

Fix: 284809020
Test: manually verified, on a large screen device with a multi-pane
settings configuration, that going to Display > Lock screen > Shortcuts
and then swiping back off the left edge of the display correctly exits
settings instead of revealing an incorrect screen like it did in the
bug.
Test: also manually verified that the long-press on the home screena and
on the lock screen paths both open the right tab in WPP in settings
correctly.

Change-Id: Iac2b4e9fa5bab91b6a5251f1c51b4d21a0824f00
2023-06-05 16:02:17 -07:00

187 lines
6.9 KiB
Java

/*
* Copyright (C) 2022 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.display;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import java.util.ArrayList;
import java.util.List;
/** Utilities for display settings related to customizable lock screen features. */
public final class CustomizableLockScreenUtils {
private static final String TAG = "CustomizableLockScreenUtils";
private static final Uri BASE_URI = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority("com.android.systemui.customization")
.build();
@VisibleForTesting
static final Uri FLAGS_URI = BASE_URI.buildUpon()
.path("flags")
.build();
@VisibleForTesting
static final Uri SELECTIONS_URI = BASE_URI.buildUpon()
.appendPath("lockscreen_quickaffordance")
.appendPath("selections")
.build();
@VisibleForTesting
static final String NAME = "name";
@VisibleForTesting
static final String VALUE = "value";
@VisibleForTesting
static final String ENABLED_FLAG =
"is_custom_lock_screen_quick_affordances_feature_enabled";
@VisibleForTesting
static final String AFFORDANCE_NAME = "affordance_name";
@VisibleForTesting
static final String WALLPAPER_LAUNCH_SOURCE = "com.android.wallpaper.LAUNCH_SOURCE";
@VisibleForTesting
static final String LAUNCH_SOURCE_SETTINGS = "app_launched_settings";
private CustomizableLockScreenUtils() {}
/**
* Queries and returns whether the customizable lock screen quick affordances feature is enabled
* on the device.
*
* <p>This is a slow, blocking call that shouldn't be made on the main thread.
*/
public static boolean isFeatureEnabled(Context context) {
if (!isWallpaperPickerInstalled(context)) {
return false;
}
try (Cursor cursor = context.getContentResolver().query(
FLAGS_URI,
null,
null,
null)) {
if (cursor == null) {
Log.w(TAG, "Cursor was null!");
return false;
}
final int indexOfNameColumn = cursor.getColumnIndex(NAME);
final int indexOfValueColumn = cursor.getColumnIndex(VALUE);
if (indexOfNameColumn == -1 || indexOfValueColumn == -1) {
Log.w(TAG, "Cursor doesn't contain " + NAME + " or " + VALUE + "!");
return false;
}
while (cursor.moveToNext()) {
final String name = cursor.getString(indexOfNameColumn);
final int value = cursor.getInt(indexOfValueColumn);
if (TextUtils.equals(ENABLED_FLAG, name)) {
Log.d(TAG, ENABLED_FLAG + "=" + value);
return value == 1;
}
}
Log.w(TAG, "Flag with name \"" + ENABLED_FLAG + "\" not found!");
return false;
} catch (Exception e) {
Log.e(TAG, "Exception while querying quick affordance content provider", e);
return false;
}
}
/**
* Queries and returns a summary text for the currently-selected lock screen quick affordances.
*
* <p>This is a slow, blocking call that shouldn't be made on the main thread.
*/
@Nullable
public static CharSequence getQuickAffordanceSummary(Context context) {
try (Cursor cursor = context.getContentResolver().query(
SELECTIONS_URI,
null,
null,
null)) {
if (cursor == null) {
Log.w(TAG, "Cursor was null!");
return null;
}
final int columnIndex = cursor.getColumnIndex(AFFORDANCE_NAME);
if (columnIndex == -1) {
Log.w(TAG, "Cursor doesn't contain \"" + AFFORDANCE_NAME + "\" column!");
return null;
}
final List<String> affordanceNames = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
final String affordanceName = cursor.getString(columnIndex);
if (!TextUtils.isEmpty(affordanceName)) {
affordanceNames.add(affordanceName);
}
}
// We don't display more than the first two items.
final int usableAffordanceNameCount = Math.min(2, affordanceNames.size());
final List<String> arguments = new ArrayList<>(usableAffordanceNameCount);
if (!affordanceNames.isEmpty()) {
arguments.add(affordanceNames.get(0));
}
if (affordanceNames.size() > 1) {
arguments.add(affordanceNames.get(1));
}
return context.getResources().getQuantityString(
R.plurals.lockscreen_quick_affordances_summary,
usableAffordanceNameCount,
arguments.toArray());
} catch (Exception e) {
Log.e(TAG, "Exception while querying quick affordance content provider", e);
return null;
}
}
/**
* Returns a new {@link Intent} that can be used to start the wallpaper picker
* activity.
*/
public static Intent newIntent() {
final Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
// By adding the launch source here, we tell our destination (in this case, the wallpaper
// picker app) that it's been launched from within settings. That way, if we are in a
// multi-pane configuration (for example, for large screens), the wallpaper picker app can
// safely skip redirecting to the multi-pane version of its activity, as it's already opened
// within a multi-pane configuration context.
intent.putExtra(WALLPAPER_LAUNCH_SOURCE, LAUNCH_SOURCE_SETTINGS);
return intent;
}
private static boolean isWallpaperPickerInstalled(Context context) {
final PackageManager packageManager = context.getPackageManager();
return newIntent().resolveActivity(packageManager) != null;
}
}