Consume work mode API

Fix: 69905244

Change-Id: I5958b3a2ebba2fa0e0f69448d5526dc72ed6a97b
This commit is contained in:
Tony Mak 2018-01-03 14:41:31 +00:00
parent cd7431d925
commit 6eeb040d86
8 changed files with 188 additions and 20 deletions

View File

@ -33,7 +33,7 @@
android:scaleType="fitXY"
android:src="@drawable/all_apps_divider"/>
<Switch
<com.android.launcher3.allapps.WorkModeSwitch
android:id="@+id/work_mode_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -37,6 +37,7 @@ import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.PowerManager;
import android.os.TransactionTooLargeException;
import android.support.v4.os.BuildCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@ -81,6 +82,8 @@ public final class Utilities {
private static final Matrix sMatrix = new Matrix();
private static final Matrix sInverseMatrix = new Matrix();
public static final boolean ATLEAST_P = BuildCompat.isAtLeastP();
public static final boolean ATLEAST_OREO_MR1 =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1;

View File

@ -18,7 +18,6 @@ package com.android.launcher3.allapps;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.UserHandle;
import android.support.animation.DynamicAnimation;
import android.support.animation.SpringAnimation;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
@ -33,7 +32,6 @@ import android.view.View.OnFocusChangeListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Switch;
import android.widget.TextView;
import com.android.launcher3.AppInfo;
@ -43,7 +41,6 @@ import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
import com.android.launcher3.anim.SpringAnimationHandler;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.discovery.AppDiscoveryAppInfo;
import com.android.launcher3.discovery.AppDiscoveryItemView;
@ -332,7 +329,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
R.layout.all_apps_divider, parent, false));
case VIEW_TYPE_WORK_TAB_FOOTER:
View footer = mLayoutInflater.inflate(R.layout.work_tab_footer, parent, false);
// TODO: Implement the work mode toggle logic here.
return new ViewHolder(footer);
default:
throw new RuntimeException("Unexpected view type");
@ -379,8 +375,8 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
// nothing to do
break;
case VIEW_TYPE_WORK_TAB_FOOTER:
Switch workModeToggle = holder.itemView.findViewById(R.id.work_mode_toggle);
workModeToggle.setChecked(!isAnyProfileQuietModeEnabled());
WorkModeSwitch workModeToggle = holder.itemView.findViewById(R.id.work_mode_toggle);
workModeToggle.refresh();
break;
}
if (mBindViewCallback != null) {
@ -549,15 +545,4 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
return factor;
}
}
private boolean isAnyProfileQuietModeEnabled() {
UserManagerCompat userManager = UserManagerCompat.getInstance(mLauncher);
List<UserHandle> userProfiles = userManager.getUserProfiles();
for (UserHandle userProfile : userProfiles) {
if (userManager.isQuietModeEnabled(userProfile)) {
return true;
}
}
return false;
}
}

View File

@ -16,6 +16,7 @@
package com.android.launcher3.allapps;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Process;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -23,11 +24,13 @@ import android.util.Log;
import com.android.launcher3.AppInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.discovery.AppDiscoveryAppInfo;
import com.android.launcher3.discovery.AppDiscoveryItem;
import com.android.launcher3.discovery.AppDiscoveryUpdateState;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ComponentKeyMapper;
import com.android.launcher3.util.ItemInfoMatcher;
@ -620,11 +623,18 @@ public class AlphabeticalAppsList {
}
// Add the work profile footer if required.
if (mIsWork) {
if (shouldShowWorkFooter()) {
mAdapterItems.add(AdapterItem.asWorkTabFooter(position++));
}
}
private boolean shouldShowWorkFooter() {
return mIsWork && Utilities.ATLEAST_P &&
(DeepShortcutManager.getInstance(mLauncher).hasHostPermission()
|| mLauncher.checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
== PackageManager.PERMISSION_GRANTED);
}
public boolean isAppDiscoveryRunning() {
return mAppDiscoveryUpdateState == AppDiscoveryUpdateState.START
|| mAppDiscoveryUpdateState == AppDiscoveryUpdateState.UPDATE;

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2018 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.launcher3.allapps;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Process;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.widget.Switch;
import com.android.launcher3.compat.UserManagerCompat;
import java.util.List;
public class WorkModeSwitch extends Switch {
public WorkModeSwitch(Context context) {
super(context);
}
public WorkModeSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setChecked(boolean checked) {
// No-op, do not change the checked state until broadcast is received.
}
@Override
public void toggle() {
trySetQuietModeEnabledToAllProfilesAsync(isChecked());
}
private void setCheckedInternal(boolean checked) {
super.setChecked(checked);
}
public void refresh() {
setCheckedInternal(!isAnyProfileQuietModeEnabled());
setEnabled(true);
}
private boolean isAnyProfileQuietModeEnabled() {
UserManagerCompat userManager = UserManagerCompat.getInstance(getContext());
List<UserHandle> userProfiles = userManager.getUserProfiles();
for (UserHandle userProfile : userProfiles) {
if (Process.myUserHandle().equals(userProfile)) {
continue;
}
if (userManager.isQuietModeEnabled(userProfile)) {
return true;
}
}
return false;
}
private void trySetQuietModeEnabledToAllProfilesAsync(boolean enabled) {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
setEnabled(false);
}
@Override
protected Boolean doInBackground(Void... voids) {
UserManagerCompat userManager = UserManagerCompat.getInstance(getContext());
List<UserHandle> userProfiles = userManager.getUserProfiles();
boolean showConfirm = false;
for (UserHandle userProfile : userProfiles) {
if (Process.myUserHandle().equals(userProfile)) {
continue;
}
showConfirm |= !userManager.trySetQuietModeEnabled(enabled, userProfile);
}
return showConfirm;
}
@Override
protected void onPostExecute(Boolean showConfirm) {
if (showConfirm) {
setEnabled(true);
}
}
}.execute();
}
}

View File

@ -33,7 +33,9 @@ public abstract class UserManagerCompat {
public static UserManagerCompat getInstance(Context context) {
synchronized (sInstanceLock) {
if (sInstance == null) {
if (Utilities.ATLEAST_NOUGAT_MR1) {
if (Utilities.ATLEAST_P) {
sInstance = new UserManagerCompatVP(context.getApplicationContext());
} else if (Utilities.ATLEAST_NOUGAT_MR1) {
sInstance = new UserManagerCompatVNMr1(context.getApplicationContext());
} else if (Utilities.ATLEAST_NOUGAT) {
sInstance = new UserManagerCompatVN(context.getApplicationContext());
@ -61,4 +63,5 @@ public abstract class UserManagerCompat {
public abstract boolean isUserUnlocked(UserHandle user);
public abstract boolean isDemoUser();
public abstract boolean trySetQuietModeEnabled(boolean enableQuietMode, UserHandle user);
}

View File

@ -82,6 +82,11 @@ public class UserManagerCompatVL extends UserManagerCompat {
return false;
}
@Override
public boolean trySetQuietModeEnabled(boolean enableQuietMode, UserHandle user) {
return false;
}
@Override
public void enableAndResetCache() {
synchronized (this) {

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2018 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.launcher3.compat;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class UserManagerCompatVP extends UserManagerCompatVNMr1 {
private static final String TAG = "UserManagerCompatVP";
private Method mTrySetQuietModeEnabledMethod;
UserManagerCompatVP(Context context) {
super(context);
// TODO: Replace it with proper API call once SDK is ready.
try {
mTrySetQuietModeEnabledMethod = UserManager.class.getDeclaredMethod(
"trySetQuietModeEnabled", boolean.class, UserHandle.class);
} catch (NoSuchMethodException e) {
Log.e(TAG, "trySetQuietModeEnabled is not available", e);
}
}
@Override
public boolean trySetQuietModeEnabled(boolean enableQuietMode, UserHandle user) {
if (mTrySetQuietModeEnabledMethod == null) {
return false;
}
try {
return (boolean)
mTrySetQuietModeEnabledMethod.invoke(mUserManager, enableQuietMode, user);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.e(TAG, "Failed to invoke mTrySetQuietModeEnabledMethod", e);
}
return false;
}
}