Bug 1365120 - Add WakeLockDelegate; r=rbarker

Add and use WakeLockDelegate within GeckoView code to replace the
notifyWakeLockChanged method in GeckoInterface. Fennec will use the
default implementation in GeckoView, while GeckoView users are free to
override the default implementation through
GeckoAppShell.setWakeLockDelegate.

MozReview-Commit-ID: I8S8q2RZRMu
This commit is contained in:
Jim Chen 2017-05-18 17:40:32 -04:00
Родитель c083d97f53
Коммит 37fd65f106
5 изменённых файлов: 110 добавлений и 47 удалений

Просмотреть файл

@ -52,7 +52,6 @@ import org.mozilla.gecko.widget.AnchoredPopup;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
@ -74,7 +73,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.PowerManager;
import android.os.StrictMode;
import android.provider.ContactsContract;
import android.provider.MediaStore.Images.Media;
@ -216,8 +214,6 @@ public abstract class GeckoApp extends GeckoActivity
private FullScreenHolder mFullScreenPluginContainer;
private View mFullScreenPluginView;
private final HashMap<String, PowerManager.WakeLock> mWakeLocks = new HashMap<String, PowerManager.WakeLock>();
protected boolean mLastSessionCrashed;
protected boolean mShouldRestore;
private boolean mSessionRestoreParsingFinished = false;
@ -2878,37 +2874,6 @@ public abstract class GeckoApp extends GeckoActivity
Permissions.onRequestPermissionsResult(this, permissions, grantResults);
}
private static final String CPU = "cpu";
private static final String SCREEN = "screen";
// Called when a Gecko Hal WakeLock is changed
@Override
// We keep the wake lock independent from the function scope, so we need to
// suppress the linter warning.
@SuppressLint("Wakelock")
public void notifyWakeLockChanged(String topic, String state) {
PowerManager.WakeLock wl = mWakeLocks.get(topic);
if (state.equals("locked-foreground") && wl == null) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (CPU.equals(topic)) {
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, topic);
} else if (SCREEN.equals(topic)) {
// ON_AFTER_RELEASE is set, the user activity timer will be reset when the
// WakeLock is released, causing the illumination to remain on a bit longer.
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, topic);
}
if (wl != null) {
wl.acquire();
mWakeLocks.put(topic, wl);
}
} else if (!state.equals("locked-foreground") && wl != null) {
wl.release();
mWakeLocks.remove(topic);
}
}
private void geckoConnected() {
mLayerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
}

Просмотреть файл

@ -435,6 +435,7 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
'sqlite/SQLiteBridge.java',
'sqlite/SQLiteBridgeException.java',
'TouchEventInterceptor.java',
'WakeLockDelegate.java',
]]
gvjar.sources += [geckoview_thirdparty_source_dir + f for f in [

Просмотреть файл

@ -34,10 +34,6 @@ public class BaseGeckoInterface implements GeckoAppShell.GeckoInterface {
@Override
public void removeAppStateListener(GeckoAppShell.AppStateListener listener) {}
// Bug 908789: Implement this
@Override
public void notifyWakeLockChanged(String topic, String state) {}
@Override
public boolean areTabsShown() {
return false;

Просмотреть файл

@ -24,7 +24,6 @@ import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import android.annotation.SuppressLint;
import org.mozilla.gecko.annotation.JNITarget;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
@ -39,6 +38,7 @@ import org.mozilla.gecko.util.ProxySelector;
import org.mozilla.gecko.util.ThreadUtils;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
@ -78,10 +78,12 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.util.SimpleArrayMap;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
@ -401,8 +403,11 @@ public class GeckoAppShell
double altitude, float accuracy,
float bearing, float speed, long time);
private static class DefaultListeners
implements SensorEventListener, LocationListener, NotificationListener, ScreenOrientationDelegate {
private static class DefaultListeners implements SensorEventListener,
LocationListener,
NotificationListener,
ScreenOrientationDelegate,
WakeLockDelegate {
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@ -533,17 +538,54 @@ public class GeckoAppShell
// Do nothing.
}
@Override
@Override // ScreenOrientationDelegate
public boolean setRequestedOrientationForCurrentActivity(int requestedActivityInfoOrientation) {
// Do nothing, and report that the orientation was not set.
return false;
}
private SimpleArrayMap<String, PowerManager.WakeLock> mWakeLocks;
@Override // WakeLockDelegate
@SuppressLint("Wakelock") // We keep the wake lock independent from the function
// scope, so we need to suppress the linter warning.
public void setWakeLockState(final String lock, final int state) {
if (mWakeLocks == null) {
mWakeLocks = new SimpleArrayMap<>(WakeLockDelegate.LOCKS_COUNT);
}
PowerManager.WakeLock wl = mWakeLocks.get(lock);
if (state == WakeLockDelegate.STATE_LOCKED_FOREGROUND && wl == null) {
final PowerManager pm = (PowerManager)
getApplicationContext().getSystemService(Context.POWER_SERVICE);
if (WakeLockDelegate.LOCK_CPU.equals(lock)) {
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lock);
} else if (WakeLockDelegate.LOCK_SCREEN.equals(lock)) {
// ON_AFTER_RELEASE is set, the user activity timer will be reset when the
// WakeLock is released, causing the illumination to remain on a bit longer.
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
PowerManager.ON_AFTER_RELEASE, lock);
} else {
Log.w(LOGTAG, "Unsupported wake-lock: " + lock);
return;
}
wl.acquire();
mWakeLocks.put(lock, wl);
} else if (state != WakeLockDelegate.STATE_LOCKED_FOREGROUND && wl != null) {
wl.release();
mWakeLocks.remove(lock);
}
}
}
private static final DefaultListeners DEFAULT_LISTENERS = new DefaultListeners();
private static SensorEventListener sSensorListener = DEFAULT_LISTENERS;
private static LocationListener sLocationListener = DEFAULT_LISTENERS;
private static NotificationListener sNotificationListener = DEFAULT_LISTENERS;
private static WakeLockDelegate sWakeLockDelegate = DEFAULT_LISTENERS;
/**
* A delegate for supporting the Screen Orientation API.
@ -582,6 +624,14 @@ public class GeckoAppShell
sScreenOrientationDelegate = (screenOrientationDelegate != null) ? screenOrientationDelegate : DEFAULT_LISTENERS;
}
public static WakeLockDelegate getWakeLockDelegate() {
return sWakeLockDelegate;
}
public void setWakeLockDelegate(final WakeLockDelegate delegate) {
sWakeLockDelegate = (delegate != null) ? delegate : DEFAULT_LISTENERS;
}
@WrapForJNI(calledFrom = "gecko")
private static void enableSensor(int aSensortype) {
GeckoInterface gi = getGeckoInterface();
@ -1649,7 +1699,6 @@ public class GeckoAppShell
public void disableOrientationListener();
public void addAppStateListener(AppStateListener listener);
public void removeAppStateListener(AppStateListener listener);
public void notifyWakeLockChanged(String topic, String state);
public boolean areTabsShown();
public void invalidateOptionsMenu();
public boolean isForegrounded();
@ -1973,9 +2022,18 @@ public class GeckoAppShell
}
@WrapForJNI(calledFrom = "gecko")
private static void notifyWakeLockChanged(String topic, String state) {
if (getGeckoInterface() != null)
getGeckoInterface().notifyWakeLockChanged(topic, state);
private static void notifyWakeLockChanged(final String topic, final String state) {
final int intState;
if ("unlocked".equals(state)) {
intState = WakeLockDelegate.STATE_UNLOCKED;
} else if ("locked-foreground".equals(state)) {
intState = WakeLockDelegate.STATE_LOCKED_FOREGROUND;
} else if ("locked-background".equals(state)) {
intState = WakeLockDelegate.STATE_LOCKED_BACKGROUND;
} else {
throw new IllegalArgumentException();
}
getWakeLockDelegate().setWakeLockState(topic, intState);
}
@WrapForJNI(calledFrom = "gecko")

Просмотреть файл

@ -0,0 +1,43 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
/**
* A <code>WakeLockDelegate</code> is responsible for acquiring and release wake-locks.
*/
public interface WakeLockDelegate {
/**
* Wake-lock for the CPU.
*/
final String LOCK_CPU = "cpu";
/**
* Wake-lock for the screen.
*/
final String LOCK_SCREEN = "screen";
final int LOCKS_COUNT = 2;
/**
* No one holds the wake-lock.
*/
final int STATE_UNLOCKED = 0;
/**
* The wake-lock is held by a foreground window.
*/
final int STATE_LOCKED_FOREGROUND = 1;
/**
* The wake-lock is held by a background window.
*/
final int STATE_LOCKED_BACKGROUND = 2;
/**
* Set a wake-lock to a specified state. Called from the Gecko thread.
*
* @param lock Wake-lock to set from one of the LOCK_* constants.
* @param state New wake-lock state from one of the STATE_* constants.
*/
void setWakeLockState(String lock, int state);
}