Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7779c83a authored by Jim Miller's avatar Jim Miller Committed by Android Git Automerger
Browse files

am fcb80423: am 8920c259: am 259e3121: am 51117262: Handle...

am fcb80423: am 8920c259: am 259e3121: am 51117262: Handle DevicePolicyManagement and safe mode when inflating widgets

* commit 'fcb80423':
  Handle DevicePolicyManagement and safe mode when inflating widgets
parents 0c8f14bd fcb80423
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3228,6 +3228,13 @@ public final class Settings {
        public static final String LOCK_SCREEN_APPWIDGET_IDS =
            "lock_screen_appwidget_ids";

        /**
         * Id of the appwidget shown on the lock screen when appwidgets are disabled.
         * @hide
         */
        public static final String LOCK_SCREEN_FALLBACK_APPWIDGET_ID =
            "lock_screen_fallback_appwidget_id";

        /**
         * Index of the lockscreen appwidget to restore, -1 if none.
         * @hide
+31 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.widget;

import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -35,6 +36,7 @@ import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.IWindowManager;
import android.view.View;
import android.widget.Button;

@@ -1112,6 +1114,25 @@ public class LockPatternUtils {
        return sb.toString();
    }

    // appwidget used when appwidgets are disabled (we make an exception for
    // default clock widget)
    public void writeFallbackAppWidgetId(int appWidgetId) {
        Settings.Secure.putIntForUser(mContentResolver,
                Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID,
                appWidgetId,
                UserHandle.USER_CURRENT);
    }

    // appwidget used when appwidgets are disabled (we make an exception for
    // default clock widget)
    public int getFallbackAppWidgetId() {
        return Settings.Secure.getIntForUser(
                mContentResolver,
                Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID,
                UserHandle.USER_CURRENT);
    }

    private void writeAppWidgets(int[] appWidgetIds) {
        Settings.Secure.putStringForUser(mContentResolver,
                        Settings.Secure.LOCK_SCREEN_APPWIDGET_IDS,
@@ -1326,4 +1347,14 @@ public class LockPatternUtils {
        return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true);
    }
    
    public static boolean isSafeModeEnabled() {
        try {
            return IWindowManager.Stub.asInterface(
                    ServiceManager.getService("window")).isSafeModeEnabled();
        } catch (RemoteException e) {
            // Shouldn't happen!
        }
        return false;
    }

}
+149 −69
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -57,7 +59,7 @@ import java.io.File;
import java.util.List;

public class KeyguardHostView extends KeyguardViewBase {
    private static final String TAG = "KeyguardViewHost";
    private static final String TAG = "KeyguardHostView";

    // Use this to debug all of keyguard
    public static boolean DEBUG = KeyguardViewMediator.DEBUG;
@@ -87,6 +89,12 @@ public class KeyguardHostView extends KeyguardViewBase {

    private Rect mTempRect = new Rect();

    private int mDisabledFeatures;

    private boolean mCameraDisabled;

    private boolean mSafeModeEnabled;

    /*package*/ interface TransportCallback {
        void onListenerDetached();
        void onListenerAttached();
@@ -113,6 +121,25 @@ public class KeyguardHostView extends KeyguardViewBase {
        mSecurityModel = new KeyguardSecurityModel(context);

        mViewStateManager = new KeyguardViewStateManager(this);

        DevicePolicyManager dpm =
            (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
        if (dpm != null) {
            mDisabledFeatures = getDisabledFeatures(dpm);
            mCameraDisabled = dpm.getCameraDisabled(null);
        }

        mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();

        if (mSafeModeEnabled) {
            Log.v(TAG, "Keyguard widgets disabled by safe mode");
        }
        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
            Log.v(TAG, "Keyguard widgets disabled by DPM");
        }
        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
            Log.v(TAG, "Keyguard secure camera disabled by DPM");
        }
    }

    @Override
@@ -177,9 +204,10 @@ public class KeyguardHostView extends KeyguardViewBase {
        }

        addDefaultWidgets();

        addWidgetsFromSettings();
        checkAppWidgetConsistency();
        mSwitchPageRunnable.run();

        // This needs to be called after the pages are all added.
        mViewStateManager.showUsabilityHints();

@@ -187,6 +215,24 @@ public class KeyguardHostView extends KeyguardViewBase {
        updateSecurityViews();
    }

    private int getDisabledFeatures(DevicePolicyManager dpm) {
        int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
        if (dpm != null) {
            final int currentUser = mLockPatternUtils.getCurrentUser();
            disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
        }
        return disabledFeatures;
    }

    private boolean widgetsDisabledByDpm() {
        return (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
    }

    private boolean cameraDisabledByDpm() {
        return mCameraDisabled
                || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
    }

    private void updateSecurityViews() {
        int children = mSecurityViewContainer.getChildCount();
        for (int i = 0; i < children; i++) {
@@ -821,15 +867,18 @@ public class KeyguardHostView extends KeyguardViewBase {
        }
    }

    private boolean addWidget(int appId, int pageIndex) {
    private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
        if (appWidgetInfo != null) {
            AppWidgetHostView view = getAppWidgetHost().createView(mContext, appId, appWidgetInfo);
            addWidget(view, pageIndex);
            return true;
        } else {
            if (updateDbIfFailed) {
                Log.w(TAG, "AppWidgetInfo for app widget id " + appId + " was null, deleting");
                mAppWidgetHost.deleteAppWidgetId(appId);
                mLockPatternUtils.removeAppWidget(appId);
            }
            return false;
        }
    }
@@ -885,16 +934,9 @@ public class KeyguardHostView extends KeyguardViewBase {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        inflater.inflate(R.layout.keyguard_transport_control_view, this, true);

        View addWidget = inflater.inflate(R.layout.keyguard_add_widget, null, true);
        if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
            View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
            mAppWidgetContainer.addWidget(addWidget);
        if (mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
            View cameraWidget =
                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
            if (cameraWidget != null) {
                mAppWidgetContainer.addWidget(cameraWidget);
            }
        }

            View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
            addWidgetButton.setOnClickListener(new OnClickListener() {
                @Override
@@ -907,6 +949,19 @@ public class KeyguardHostView extends KeyguardViewBase {
                    }
                }
            });
        }

        // We currently disable cameras in safe mode because we support loading 3rd party
        // cameras we can't trust.  TODO: plumb safe mode into camera creation code and only
        // inflate system-provided camera?
        if (!mSafeModeEnabled && !cameraDisabledByDpm()
                && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
            View cameraWidget =
                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
            if (cameraWidget != null) {
                mAppWidgetContainer.addWidget(cameraWidget);
            }
        }

        enableUserSelectorIfNecessary();
        initializeTransportControl();
@@ -969,14 +1024,15 @@ public class KeyguardHostView extends KeyguardViewBase {
        }
    }

    private int getAddPageIndex() {
    private int getInsertPageIndex() {
        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
        int addPageIndex = mAppWidgetContainer.indexOfChild(addWidget);
        // This shouldn't happen, but just to be safe!
        if (addPageIndex < 0) {
            addPageIndex = 0;
        int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
        if (insertionIndex < 0) {
            insertionIndex = 0; // no add widget page found
        } else {
            insertionIndex++; // place after add widget
        }
        return addPageIndex;
        return insertionIndex;
    }

    private void addDefaultStatusWidget(int index) {
@@ -986,18 +1042,11 @@ public class KeyguardHostView extends KeyguardViewBase {
    }

    private void addWidgetsFromSettings() {
        DevicePolicyManager dpm =
                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
        if (dpm != null) {
            final int currentUser = mLockPatternUtils.getCurrentUser();
            final int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
            if ((disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
                Log.v(TAG, "Keyguard widgets disabled because of device policy admin");
        if (mSafeModeEnabled || widgetsDisabledByDpm()) {
            return;
        }
        }

        int addPageIndex = getAddPageIndex();
        int insertionIndex = getInsertPageIndex();

        // Add user-selected widget
        final int[] widgets = mLockPatternUtils.getAppWidgets();
@@ -1007,50 +1056,90 @@ public class KeyguardHostView extends KeyguardViewBase {
        } else {
            for (int i = widgets.length -1; i >= 0; i--) {
                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
                    addDefaultStatusWidget(addPageIndex + 1);
                    addDefaultStatusWidget(insertionIndex);
                } else {
                    // We add the widgets from left to right, starting after the first page after
                    // the add page. We count down, since the order will be persisted from right
                    // to left, starting after camera.
                    addWidget(widgets[i], addPageIndex + 1);
                    addWidget(widgets[i], insertionIndex, true);
                }
            }
        }
        checkAppWidgetConsistency();
    }

    private int allocateIdForDefaultAppWidget() {
        int appWidgetId;
        Resources res = getContext().getResources();
        ComponentName defaultAppWidget = new ComponentName(
                res.getString(R.string.widget_default_package_name),
                res.getString(R.string.widget_default_class_name));

        // Note: we don't support configuring the widget
        appWidgetId = mAppWidgetHost.allocateAppWidgetId();

        try {
            mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);

        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
            appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
        }
        return appWidgetId;
    }

    public void checkAppWidgetConsistency() {
        final int childCount = mAppWidgetContainer.getChildCount();
        boolean widgetPageExists = false;
        for (int i = 0; i < childCount; i++) {
            if (isWidgetPage(i)) {
            if (mAppWidgetContainer.isWidgetPage(i)) {
                widgetPageExists = true;
                break;
            }
        }
        if (!widgetPageExists) {
            final int addPageIndex = getAddPageIndex();
            final int insertPageIndex = getInsertPageIndex();

            Resources res = getContext().getResources();
            ComponentName defaultAppWidget = new ComponentName(
                    res.getString(R.string.widget_default_package_name),
                    res.getString(R.string.widget_default_class_name));
            final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm();
            boolean addedDefaultAppWidget = false;

            // Note: we don't support configuring the widget
            int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
            boolean bindSuccessful = false;
            try {
                mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
                bindSuccessful = true;
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
            if (!mSafeModeEnabled) {
                if (userAddedWidgetsEnabled) {
                    int appWidgetId = allocateIdForDefaultAppWidget();
                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
                    }
                } else {
                    // note: even if widgetsDisabledByDpm() returns true, we still bind/create
                    // the default appwidget if possible
                    int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
                    if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
                        appWidgetId = allocateIdForDefaultAppWidget();
                        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
                            mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
                        }
                    }
                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
                        if (!addedDefaultAppWidget) {
                            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
                            mLockPatternUtils.writeFallbackAppWidgetId(
                                    AppWidgetManager.INVALID_APPWIDGET_ID);
                        }
                    }
                }
            }

            // Use the built-in status/clock view if we can't inflate the default widget
            if (!(bindSuccessful && addWidget(appWidgetId, addPageIndex + 1))) {
                addDefaultStatusWidget(addPageIndex + 1);
            if (!addedDefaultAppWidget) {
                addDefaultStatusWidget(insertPageIndex);
            }

            // trigger DB updates only if user-added widgets are enabled
            if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
                mAppWidgetContainer.onAddView(
                    mAppWidgetContainer.getChildAt(addPageIndex + 1), addPageIndex + 1);
                        mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
            }
        }
    }

@@ -1154,15 +1243,6 @@ public class KeyguardHostView extends KeyguardViewBase {
        return null;
    }

    private boolean isWidgetPage(int pageIndex) {
        View v = mAppWidgetContainer.getChildAt(pageIndex);
        if (v != null && v instanceof KeyguardWidgetFrame) {
            KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
            return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
        }
        return false;
    }

    private int getStickyWidget() {
        // The first time we query the persistent state. From that point, we use a locally updated
        // notion of the sticky widget page.
+1 −0
Original line number Diff line number Diff line
@@ -260,4 +260,5 @@ public abstract class KeyguardViewBase extends FrameLayout {
            KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
        mViewMediatorCallback = viewMediatorCallback;
    }

}
+18 −29
Original line number Diff line number Diff line
@@ -22,9 +22,9 @@ import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.AttributeSet;
@@ -38,7 +38,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;

import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;

import java.util.ArrayList;
@@ -69,8 +68,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
    private int mPage = 0;
    private Callbacks mCallbacks;

    private boolean mCameraWidgetEnabled;

    private int mWidgetToResetAfterFadeOut;

    // Bouncer
@@ -97,10 +94,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit

        setPageSwitchListener(this);

        Resources r = getResources();
        mCameraWidgetEnabled = r.getBoolean(R.bool.kg_enable_camera_default_widget);
        mCenterSmallWidgetsVertically =
                r.getBoolean(com.android.internal.R.bool.kg_center_small_widgets_vertically);
        mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
        mBackgroundWorkerThread.start();
        mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
@@ -502,33 +495,29 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
        }
    }

    public boolean isWidgetPage(int pageIndex) {
        if (pageIndex < 0 || pageIndex >= getChildCount()) {
            return false;
        }
        View v = getChildAt(pageIndex);
        if (v != null && v instanceof KeyguardWidgetFrame) {
            KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
            return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
        }
        return false;
    }

    @Override
    void boundByReorderablePages(boolean isReordering, int[] range) {
        if (isReordering) {
            if (isAddWidgetPageVisible()) {
                range[0]++;
            }
            if (isMusicWidgetVisible()) {
            // Remove non-widget pages from the range
            while (range[1] > range[0] && !isWidgetPage(range[1])) {
                range[1]--;
            }
            if (isCameraWidgetVisible()) {
                range[1]--;
            }
        }
    }

    /*
     * Special widgets
     */
    boolean isAddWidgetPageVisible() {
        // TODO: Make proper test once we decide whether the add-page is always showing
        return true;
            while (range[0] < range[1] && !isWidgetPage(range[0])) {
                range[0]++;
            }
    boolean isMusicWidgetVisible() {
        return mViewStateManager.getTransportState() != KeyguardViewStateManager.TRANSPORT_GONE;
        }
    boolean isCameraWidgetVisible() {
        return mCameraWidgetEnabled;
    }

    protected void reorderStarting() {
@@ -785,7 +774,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit

    boolean isAddPage(int pageIndex) {
        View v = getChildAt(pageIndex);
        return v != null && v.getId() == R.id.keyguard_add_widget;
        return v != null && v.getId() == com.android.internal.R.id.keyguard_add_widget;
    }

    boolean isCameraPage(int pageIndex) {